Python3.x基础学习-类--多继承、多态
多继承
一个子类继承多个父类,就是多继承,并且拥有所有父类的属性和方法
例如:孩子会继承父亲和母亲的特征
如果子类和父类中有相同的方法,就会调用子类中的方法
如果不同的父类中存在有相同的方法名称,子类对象调用的时候会调用哪个父类中的方法呢?
python 会根据MRO(method resolution order) 方法解析顺序列表进行查找。
class Dog: def eat(self): print("吃骨头") class God: def eat(self): print("吃上帝") class Thing(God,Dog): pass thing = Thing() thing.eat() print(Thing.__mro__) # 吃上帝 # (<class '__main__.Thing'>, <class '__main__.God'>, <class '__main__.Dog'>, <class 'object'>)
MRO列表并遵循如下三条准则:
1.子类会先于父类被检查
2.多个父类会根据他们在列表中的顺序进行检查
3.如果对下一个类中有两个合法的选择,选择第一个父类
class A: def func(self): print("----A----") class B(A): def func(self): print("----B----") class C(A): def func(self): print("----B-----") class D(B,C): pass d = D() d.func() print(D.__mro__) print(D.mro()) # ----B---- # (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>) # [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
多继承中super本质不是直接查找父类,而是根据调用节点的广度优先顺序执行的
练习:创建 A、B、C、D 类,D 类继承 B,C 类,B 类继承 A 类,C 类继承 A 类。
在每个方法中都调用 super().func()方法,查看执行顺序。
class A: def func(self): print("----A----") class B(A): def func(self): super(B, self).func() print("----B----") class C(A): def func(self): super(C, self).func() print("----C-----") class D(B,C): def func(self): super(D, self).func() print("----D-----") d = D() d.func() # 继承顺序 D-->B-->C-->A #结果:A,C,B,D print(D.__mro__) print(D.mro()) # (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>) # [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
如图,B 继承 A, C 继承 A, D 继承 B 和 C。
深度优先遍历是从 D 开始往上搜索到 B,若 B 没有数据,则继续往上搜索到 A;
广度优先遍历是从 D 开始往上搜索到 B,若 B 没有数据,则搜索和 B 同级的 C 里的数据,若同级的 C 里还是没有数据,再继续往上搜索到 A 。
Tips:py2 经典类是按深度优先来继承的,新式类是按广度优先来继承的。
py3 经典类和新式类都是统一按广度优先来继承的
class A: def func(self): print("----A----") class B(A): def func(self): super(B, self).func() print("----B----") class C(A): def func(self): super(C, self).func() print("----C-----") class D(B): def func(self): super(D, self).func() print("----D-----") class E(C): def func(self): super(E, self).func() print("----E-----") class F(D, E): def func(self): super(F, self).func() print("----F-----") f = F() f.func() # 继承顺序 D-->B-->C-->A # ----A---- # ----C----- # ----E----- # ----B---- # ----D----- # ----F-----
class A: def func(self): print("----A----") class B(A): def func(self): super(B, self).func() print("----B----") class C(A): def func(self): super(C, self).func() print("----C-----") class D(C): def func(self): super(D, self).func() print("----D-----") class E(B): def func(self): super(E, self).func() print("----E-----") class G(B): def func(self): super(G, self).func() print("----G-----") class H(A): def func(self): super(H, self).func() print("----H-----") class F(D, E,G,H): def func(self): super(F, self).func() print("----F-----") f = F() f.func() # ----A---- # ----H----- # ----B---- # ----G----- # ----E----- # ----C----- # ----D----- # ----F-----
class A1: pass class A2: pass class A3: pass class B1(A1,A2): pass class B2(A2): pass class B3(A2,A3): pass class C1(B1): pass class C2(B1,B2): pass class C3(B2,B3): pass class D(C1, C2, C3): pass print("从D开始查找:") for s in D.__mro__: print(s) # 从D开始查找: # <class '__main__.D'> # <class '__main__.C1'> # <class '__main__.C2'> # <class '__main__.B1'> # <class '__main__.A1'> # <class '__main__.C3'> # <class '__main__.B2'> # <class '__main__.B3'> # <class '__main__.A2'> # <class '__main__.A3'># <class 'object'>
多态
面向对象三大特性: 封装、继承、多态
1.封装:屏蔽提供细节,但提供调用方式,将功能封装成一个整体,提供简单的调用方式
2.继承:可以拥有另一个类的方法和属性
3.多态:让某个类呈现多种形态
实现多态的三个条件: 1.必须存在继承关系 2.重写目标方法 3.使用子类对象调用父类方法
定义人类,可以跳舞,可以玩,在玩的过程跳舞
实现多态,老年人跳广场舞
class Person: def dance(self): print('跳舞') def play(self): self.dance() #old.dance() class Oldman(Person): def dance(self): print("跳广场舞") old = Oldman() old.play() per = Person() per.play()