在 Python 中,继承是一个非常强大的特性,它允许我们创建一个新类(子类),该类可以继承另一个类(父类)的属性和方法。有时候,我们需要在子类中修改或扩展父类的方法,这就是所谓的“方法重写”。本文将详细介绍如何在 Python 子类中重写父类方法,从基础到进阶,一步步带你掌握这个重要技能。
基础概念
首先,我们来看一个简单的例子,了解一下什么是方法重写。
# 定义一个父类
class Animal:
def speak(self):
return "Some sound"
# 定义一个子类,继承自 Animal
class Dog(Animal):
def speak(self):
return "Woof woof!"
# 创建一个 Dog 对象
dog = Dog()
# 调用 speak 方法
print(dog.speak()) # 输出: Woof woof!
在这个例子中,Dog 类继承了 Animal 类,并且重写了 speak 方法。当我们调用 Dog 对象的 speak 方法时,会执行 Dog 类中的 speak 方法,而不是 Animal 类中的 speak 方法。
使用 super() 调用父类方法
有时候,我们不仅想重写父类的方法,还想在子类中调用父类的方法。这时,可以使用 super() 函数。
# 定义一个父类
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return f"{self.name} makes a sound"
# 定义一个子类,继承自 Animal
class Dog(Animal):
def __init__(self, name):
super().__init__(name) # 调用父类的初始化方法
def speak(self):
return super().speak() + " - Woof woof!" # 调用父类的 speak 方法并添加额外信息
# 创建一个 Dog 对象
dog = Dog("Buddy")
# 调用 speak 方法
print(dog.speak()) # 输出: Buddy makes a sound - Woof woof!
在这个例子中,Dog 类的 __init__ 方法和 speak 方法都使用了 super() 来调用父类的相应方法。这样可以在子类中扩展父类的功能,而不仅仅是完全替换。
重写特殊方法
Python 中有一些特殊方法(也称为魔术方法),如 __str__、__len__ 等。这些方法可以被重写以改变对象的行为。
# 定义一个父类
class Person:
def __init__(self, name):
self.name = name
def __str__(self):
return f"Person: {self.name}"
# 定义一个子类,继承自 Person
class Student(Person):
def __init__(self, name, grade):
super().__init__(name)
self.grade = grade
def __str__(self):
return super().__str__() + f", Grade: {self.grade}"
# 创建一个 Student 对象
student = Student("Alice", 10)
# 打印 Student 对象
print(student) # 输出: Person: Alice, Grade: 10
在这个例子中,Student 类重写了 __str__ 方法,使其返回包含学生年级的信息。
多重继承中的方法重写
Python 支持多重继承,即一个类可以继承多个父类。在这种情况下,方法重写的规则会稍微复杂一些。
# 定义两个父类
class Father:
def speak(self):
return "Father's voice"
class Mother:
def speak(self):
return "Mother's voice"
# 定义一个子类,继承自 Father 和 Mother
class Child(Father, Mother):
def speak(self):
return super().speak() + " - Child's voice"
# 创建一个 Child 对象
child = Child()
# 调用 speak 方法
print(child.speak()) # 输出: Father's voice - Child's voice
在这个例子中,Child 类继承了 Father 和 Mother 类。由于 Father 类在继承列表中排在前面,所以 super().speak() 会调用 Father 类的 speak 方法。
实战案例:银行账户系统
假设我们要设计一个银行账户系统,其中有一个基本的 Account 类和一个继承自 Account 的 SavingsAccount 类。SavingsAccount 类需要重写 withdraw 方法,以实现不同的取款逻辑。
# 定义一个基本的 Account 类
class Account:
def __init__(self, balance):
self.balance = balance
def deposit(self, amount):
self.balance += amount
return self.balance
def withdraw(self, amount):
if amount <= self.balance:
self.balance -= amount
return self.balance
else:
return "Insufficient funds"
# 定义一个 SavingsAccount 类,继承自 Account
class SavingsAccount(Account):
def __init__(self, balance, interest_rate):
super().__init__(balance)
self.interest_rate = interest_rate
def withdraw(self, amount):
# 取款前检查余额是否足够
if amount <= self.balance:
# 检查取款金额是否超过余额的 50%
if amount > self.balance * 0.5:
return "Withdrawal amount exceeds 50% of balance"
self.balance -= amount
return self.balance
else:
return "Insufficient funds"
# 创建一个 SavingsAccount 对象
savings_account = SavingsAccount(1000, 0.05)
# 存款
print(savings_account.deposit(500)) # 输出: 1500
# 取款
print(savings_account.withdraw(700)) # 输出: Withdrawal amount exceeds 50% of balance
print(savings_account.withdraw(500)) # 输出: 1000
在这个例子中,SavingsAccount 类重写了 withdraw 方法,增加了取款金额不能超过余额 50% 的限制。这样可以更好地控制账户的安全性和稳定性。
总结
本文详细介绍了如何在 Python 子类中重写父类方法,从基础的概念到高级的多重继承和实战案例。通过这些例子,你应该能够理解方法重写的基本原理和应用场景。