一个子类可以继承多个父类,就是多继承,并且拥有所有父类的属性和方法。
例如 孩子会继承自己的父亲和母亲的特征。
1、语法
class 子类名(父类名1,父类名2…) : pass
class A(object):
num_a = 10
def test1(self):
print('A test1')
def teset2(self):
print('A test2')
class B(object):
num_b = 20
def test1(self):
print('B test3')
def teset4(self):
print('B test4')
class C(A, B):
def test5(self):
print('C test5')
c = C()
c.test1() # A test1
c.teset2() # A test2
c.teset4() # B test4
print(C.num_a) # 10
print(C.num_b) # 20
c.test5() # C test5
# 父类有相同的方法的时候会调用哪一个呢?
创建子类时,会按照继承的父类的顺序优先调用前面父类的方法
#Python会根据 MRO(method resolution order) 方法解析顺序列表进行查找。方法如下:
print(C.mro()) # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
print(C.__mro__) # (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
# 使用mro()方法来查看类的搜索路径
运行结果;
A test1
A test2
B test4
10
20
C test5
A test1
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
2、继承原理:
python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表
为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:
1.子类会先于父类被检查
2.多个父类会根据它们在列表中的顺序被检查
3.如果对下一个类存在两个合法的选择,选择第一个父类
简单举例:
class A(object):
def test1(self):
print('A teset')
class B(A):
def test(self):
print('B test')
class C(A):
def test(self):
print('C test')
class D(B,C):
def test(self):
print('D test')
print(D.mro()) # 解析顺序列表
运行结果:
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
解析顺序过程:
3、多继承中super本质
不是直接查找父类,而是根据调用节点的广度优先顺序执行的。
class A(object):
def test(self):
print('A teset')
class B(A):
def test(self):
super().test()
print('B test')
class C(A):
def test(self):
super().test()
print('C test')
class D(B, C):
def test(self):
super().test()
print('D test')
d = D()
d.test()
print(D.mro())
运行结果:
A teset
C test
B test
D test
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
运行过程: