day20 面向对象06 MRO和C3算法
1. 多继承
继承: x是一种y的时候.可以使用继承关系. "is a"
一个类同时继承多个类(python, c++)
孙悟空是一种猴子, 还是一种神仙
2. 经典类的MRO python2.2之前使用
一条道走到黑(从左往右)
下图顺序是 123456 则为深度优先遍历
如果是142356 , 则为广度优先遍历
![](https://img2018.cnblogs.com/blog/1513668/201811/1513668-20181113210634842-424196407.png)
3. 新式类的MRO(重点, 难点) C3算法 python2.3 开始使用
先拆分
再合并
merge的原则是⽤每个元组的头⼀项和后⾯元组的除头⼀项外的其他元
素进⾏比较, 看是否存在. 如果存在. 就从下⼀个元组的头⼀项继续找. 如果找不到. 就拿出来 . 当元组全部找完,需要重头开始寻找(循环使用这个方法)
4. super() (重点)
使用MRO顺序寻找父类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class ShengWu: def dong(self): # 实例方法 print(self) print("我是生物") class Animal(ShengWu): pass class Cat(Animal): def dong(self): # 子类中出现了和父类重名的内容. 表示对父类的方法的覆盖(重写). 半盖(java) super(Animal, self).dong() # 定位到Animal. 找Animal的下一个 # super(类, 对象).方法() 找到MRO中的类. 找这个类的下一个. 去执行方法 print("我的猫也会动") # 找MRO中的下一个 # Cat -> Animal -> ShengWu
print(类名.__mro__) 可以打印多继承的MRO顺序
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# MRO + super ⾯试题 class Init(object): def __init__(self, v): print("init") self.val = v # 2 class Add2(Init): def __init__(self, val): # 2 print("Add2") super(Add2, self).__init__(val) print(self.val) # 5.0 self.val += 2 # 7.0 class Mult(Init): def __init__(self, val): print("Mult") super(Mult, self).__init__(val) self.val *= 5 # 5.0 class HaHa(Init): def __init__(self, val): print("哈哈") super(HaHa, self).__init__(val) self.val /= 5 # 1.0 class Pro(Add2,Mult,HaHa): # pass class Incr(Pro): def __init__(self, val): # 5 super(Incr, self).__init__(val) self.val += 1 # 8.0 # Incr, pro, add2, mult, haha, Init p = Incr(5) print(p.val) # ? # Add2 init c = Add2(2) print(c.val) # ? 答案 ''' add2 Mult 哈哈 init 5.0 8.0 Add2 init 2 4 ''' 结论: 不管super()写在哪⼉. 在哪⼉执⾏. ⼀定先找到MRO列表. 根据 MRO列表的顺序往下找. 否则⼀切都是错的