7.1 方法 super()
既然我们谈到了继承体系,那么聊聊如何处理基类的字段和方法的细节就很有帮助。在 Python 中,有一个 特别的方法 super()。这个方法用于在子类中调用基类的方法。
它有三个主要的应用场景:
调用父类的方法:
方法 super() 允许从子类中调用父类的方法,而无需显式指定父类的名称。这在处理多重继承时特别有用,可以帮助避免在更改类层次结构时出现错误。
初始化基类:
super() 常用于子类的构造函数中,以便调用基类的构造函数,从而在子类中初始化基类的属性。
支持多重继承:
在多重继承的情况下,super() 会正确解析方法调用的顺序(MRO,Method Resolution Order),这使得它比显式调用父类的方法更好。我们稍后会谈到这个。
7.2 基类的构造函数
基类的构造函数必须显式调用。看起来像是自动发生的,但其实并不是这样。基类的构造函数总是需要显式调用,因为经常需要传递特殊的参数给它们。
例子:
class Animal:
def __init__(self, type, name):
self.type = type
self.name = name
class Dog(Animal):
def __init__(self, name):
super().__init__("狗", name) # 调用基类的构造函数
class Cat(Animal):
def __init__(self, name):
super().__init__("猫", name) # 调用基类的构造函数
# 创建 Dog 对象
dog = Dog("Buddy")
print(dog)
在这个例子中,基类构造函数 (Animal) 有两个参数:动物的类型和它的名字。而子类只有一个——只有名字。
正是在类 Dog 和 Cat 的构造函数中,决定传递什么参数给基类构造函数——动物类型“狗”和“猫”。
所以:
- 必须在子类的构造函数中调用基类的构造函数。
- 为此需要使用方法
super()。 - 不需要单独传递参数
self—— Python 会在调用方法时自动填入它。
7.3 方法 super() 的使用
方法 super() 在 Python 中不仅可以用于构造函数,还可以用于类的其他方法中调用父类的方法。这在需要扩展或修改父类中定义的方法行为时可能很有用。
让我们来看几个例子:
在子方法中调用父类的方法
在这个例子中,类 Dog 的方法 speak() 先调用类 Animal 的 speak() 方法,再加上自己的行为。
class Animal:
def speak(self):
return "一些通用的动物声音"
class Dog(Animal):
def speak(self):
parent_speech = super().speak() # 调用父类的方法
return f"{parent_speech} 并且狗叫!"
dog = Dog()
print(dog.speak()) # 输出: 一些通用的动物声音并且狗叫!
在检查状态时调用父类的方法
在这个例子中,类 Dog 的方法 check_health() 调用类 Animal 的 check_health() 方法,以便添加额外的检查。
class Animal:
def check_health(self):
return "动物很健康"
class Dog(Animal):
def check_health(self):
parent_check = super().check_health() # 调用父类的方法
return f"{parent_check}。狗需要散步!"
dog = Dog()
print(dog.check_health()) # 输出: 动物很健康。狗需要散步!
在更改状态的方法中调用父类的方法
在这个例子中,类 SavingsAccount 的方法 withdraw() 先检查是否超过取款限制,如果没有,则调用类 BankAccount 的 withdraw() 方法来执行操作。
class BankAccount:
def __init__(self, balance):
self.balance = balance
def withdraw(self, amount):
if self.balance >= amount:
self.balance -= amount
return f"取款 {amount}。新余额: {self.balance}"
return "资金不足"
class SavingsAccount(BankAccount):
def withdraw(self, amount):
if amount > 1000:
return "超出取款限额"
return super().withdraw(amount) # 调用父类的方法
savings = SavingsAccount(1500)
print(savings.withdraw(500)) # 输出: 取款 500。新余额: 1000
print(savings.withdraw(1500)) # 输出: 超出取款限额
GO TO FULL VERSION