子类调用父类的两种方法:
bash
方法1:
父类名.父类方法名()
# 可以调用多个父类的方法
scss
方法2:
super().父类方法名()
# 只能调用第一个父类的方法
为什么不用方法2完全替代方法1?
父类名.父类方法名()不适用于多继承的情况。
多继承
方法一:
class A(object):
def __init__(self):
print('A初始化')
class B(A):
def __init__(self):
A.__init__(self)
print('B初始化')
class C(A):
def __init__(self):
A.__init__(self)
print('C初始化')
class D(B,C):
def __init__(self):
B.__init__(self)
C.__init__(self)
print('D初始化')
if __name__ == '__main__':
d = D()
输出结果
输出结果:
A初始化 #第一次调用
B初始化
A初始化 #第二次调用,重复调用
C初始化
D初始化
可以看到A被调用了两次,可能会引发数据重复初始化,资源浪费甚至是错误。
多继承
方法二:
class A(object):
def __init__(self):
print('A初始化')
class B(A):
def __init__(self):
super().__init__()
print('B初始化')
class C(A):
def __init__(self):
super().__init__()
print('C初始化')
class D(B,C):
def __init__(self):
# 自动按 MRO 顺序调用,只调用一次 A.__init__
super().__init__()
print('D初始化')
if __name__ == '__main__':
d = D()
输出结果
输出结果:
A初始化
C初始化
B初始化
D初始化
使用super(),A只被初始化了一次,遵循方法解析顺序(MRO)。
父类名.父类方法名()会导致代码耦合性强,如果父类改名或者继承结构变动,需要手动修改子类调用。
super()是动态的,会根据类的继承关系自动查找父类,无需编码类名。
父类名.父类方法名()无法支持多协作式继承,即多个类协同完成一个任务。每个类都调用super().method()来传递控制权。
代码
多协作式继承:
class PluginA:
def setup(self):
print("PluginA 设置")
super().setup() # 让下一个类继续设置
class PluginB:
def setup(self):
print("PluginB 设置")
class Combined(PluginA, PluginB):
def setup(self):
print("Combined 设置")
super().setup()
c = Combined()
c.setup()
!!!记住:super() 不是"调用父类",而是"调用 MRO 中的下一个类"。如果那个类没有对应方法,就会报错。!!!