# 多继承:
# 在继承关系中.⼦类自动拥有⽗类中除私有属性外其他所有内容.python⽀持多继承.子类可拥有多⽗类.
class ShenXian: # 神仙
def fei(self):
print("神仙都会⻜")
class Monkey: # 猴
def chitao(self):
print("猴⼦喜欢吃桃⼦")
class SunWukong(ShenXian, Monkey): # 孙悟空是神仙, 同时也是⼀只猴(自己有先自己,然后靠最近的,再其他)
pass
# sxz = SunWukong() # 孙悟空
# sxz.chitao() # 会吃桃⼦
# sxz.fei() # 会⻜
# 这就是多继承,但当两个⽗类中出现了重名⽅法的时候.就涉及到如何查找⽗类⽅法的问题.
# 即下面的 MRO(method resolution order) 问题
# 经典类MRO算法:
# 在python2.2之前用,现已弃用(做面试题参考) 采用的树形结构的深度递归遍历
# 方法:从头开始.从左往右,一条道跑到底,然后回头.继续⼀条路跑到头.(画图)
# 画图排顺序 现用python版本已无法验证
class A:
pass
class B(A):
pass
class C(A):
pass
class D(B, C):
pass
class E:
pass
class F(D, E):
pass
class G(F, D):
pass
class H:
pass
class Foo(H, G):
pass
# 结果 : FOO--H--G--F--D--B--A--C--E
# 新式类MRO算法(C3):
# 先拆后合 从下向上合并,拿出每一项的头和后一项的身体进行比较.
# 如果出现了就过,从后一项的头继续去比较.如果不出现就出来放到结果。
# (注意:每次都是拿 头一项 的头和后面的身体比较,出现了就过,这时把后一项的头作为头一项继续去比较,
# 若后一项的头在后面身体还有,继续这个操作...直到后面身体没有再返回前面的头,理解成一个循环)
class A:
pass
class B(A):
pass
class C(A):
pass
class D(B, C):
pass
class E(C, A):
pass
class F(D, E):
pass
class M(F, E):
pass
class N:
pass
class P(M,N):
pass
class G(P):
pass
class O:
pass
class X(O):
pass
class H(G, X, F):
pass
print(H.__mro__)
'''
# 拆 注意别漏了末尾的 “GXF”
# 当类里面只有单个继承时不需要
L(H) = H + L(G) + L(X) + L(F) + GXF HGPMXFDBECANO
L(G) = G + L(P) GPMFDBECAN
L(X) = X + L(O) XO
L(F) = F + L(D) + L(E) + DE FDBECA
L(P) = P + L(M) + L(N) + MN PMFDBECAN
L(O) = O
L(D) = D + L(B) + L(C) + BC DBCA
L(E) = E + L(C) + L(A) + CA ECA
L(M) = M + L(F) + L(E) + FE MFDBECA
L(N) = N
L(B) = B + L(A) BA
L(C) = C + L(A) CA
L(A) = A
# HGPMXFDBECANO
# super():
# super是查找mro顺序中的下一个
# 单继承中我们可以认为super是对父类中的属性或方法的引入
# super()常用地方:
# 1.访问⽗类的构造⽅法
# 2.⼦类⽅法调⽤⽗类(MRO)中的⽅法
# 访问⽗类的构造⽅法
class Foo1:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
class Bar(Foo1):
def __init__(self, a, b, c, d):
super().__init__(a, b, c) # 访问⽗类的构造⽅法 对父类中的属性引入
self.d = d
b = Bar(1, 2, 3, 4)
print(b.__dict__) # {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# 当⼦类⽅法想调⽤⽗类(MRO)⽅法
class ShengWu:
def dong(self): # 实例方法
print(self)
print("我是生物")
class Animal(ShengWu):
pass
class Cat(Animal):
def dong(self): # 子类中出现了和父类重名的内容. 表示对父类的方法的覆盖(重写).
super(Animal, self).dong() # 定位到Animal. 找Animal的下一个
# super(类, 对象).方法() 找MRO中的类. 找这个类的下一个. 去执行方法
print("我的猫也会动")
# self 依然是谁调用就是谁
# 找MRO中的下一个
# Cat -> Animal -> ShengWu ->Object
c = Cat()
print(c)
c.dong()
# 总结 不管super()写在哪⼉.在哪⼉执⾏.⼀定先找MRO列表.根据MRO列表的顺序往下找.否则⼀切都是错的