class Parent:
pass
class Child(Parent):
pass
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print("Animal speaks")
class Dog(Animal):
def speak(self): # 直接覆盖父类
print("Dog speaks")
print(f"{self.name} speaks") # 父类属性调用
d = Dog("ali")
d.speak()
# Dog speaks
# ali speaks
在子类中可以重写父类的所有方法,当然也包括__init__()方法。
class Parent1:
def method(self):
print("Parent1's method")
class Parent2:
def method(self):
print("Parent2's method")
class Child(Parent1, Parent2):
def call_methods(self):
# 调用 Parent1 的 method()
# 为什么是Parent1是基于C3算法
super().method()
# 直接调用 Parent2 的 method()
# 个人觉得这个写法好,逻辑明了
Parent2.method(self)
child = Child()
child.call_methods()
在多继承中,当继承的父类中都有一个名字相同的方法,当子类实例调用这个方法时,使用的是方法解析顺序(Method Resolution Order,MRO)。
方法解析顺序是一种确定多继承中属性和方法搜索顺序的算法。在 Python 中,方法解析顺序是通过 C3 算法来计算的。该算法会按照深度优先搜索(DFS)的顺序,从左到右查找继承树中的属性和方法。
对于一个继承了多个父类的子类,其方法解析顺序可以通过__mro__属性获取。
例如,在上面的例子中,我们可以通过以下代码获取 Child类的方法解析顺序:
print(Child.__mro__)
输出结果为:
(<class '__main__.Child'>, <class '__main__.Parent1'>, <class '__main__.Parent2'>, <class 'object'>)
这表明在调用 Child类的方法时,会按照 <class ‘main.Child’>, <class ‘main.Parent1’>, <class ‘main.Parent2’> 和 <class ‘object’> 的顺序依次查找。
如果多个父类中存在相同的方法名,则会按照方法解析顺序,依次从左到右查找,直到找到第一个匹配的方法为止。如果在所有父类中都找不到匹配的方法,则会抛出 AttributeError 异常。
super() 函数用于在子类中调用父类的方法。
使用 super() 的一种常见方式是在子类的方法中调用父类的同名方法。通过使用 super().method_name(),可以保证调用的是父类的方法而不是子类的重写方法。
class ParentClass:
def method(self):
print("ParentClass method")
class ChildClass(ParentClass):
def method(self):
super().method() # 调用父类的 method 方法
print("ChildClass method")
# 创建一个 ChildClass 类的实例
child = ChildClass()
child.method()
# ParentClass method
# ChildClass method
在这个例子中,子类 ChildClass 继承了父类 ParentClass 的方法 method。在子类的 method 方法中,我们通过 super().method() 调用了父类的 method 方法,并在之后添加了子类特定的逻辑。
需要注意的是,super() 函数只能用于新式类(继承自 object 或其他新式类的类),而对于旧式类则无法使用。在 Python 3 中,默认情况下所有的类都是新式类,所以 super() 可以广泛使用。
使用 super() 的优点包括:
然而,并非所有情况下都需要使用 super()。以下是一些情况下可能不需要使用 super() 的例子:
如有错误欢迎评论指正,
如有问题欢迎评论提问。