前言:
继承是面向对象的3大特性之一,对于继承一点要注意一下4点。
一、基本查找
如果子类继承了父类,子类的实例化对象,没有的方法和属性会去父类找
class Parent(object): #父类 def f1(self): print('f1') class Sub(Parent): #子类 pass obj=Sub() #如果子类继承了父类,子类的实例化对象,没有的方法和属性会去父类BAR() obj.f1()
二、多继承查找顺序
python中的类支持继承多个类,在Java和C#中则不会存在;
如果Python中的类如果继承了多个类,其寻找方式无非2种,分别是深度优先,广度优先;
pyton2如果没有继承object默认使用的是经典类:所有经典类使用深度优先的算法查找顺序
Python3默认使用新式类:所有经典类使用广度优先的查询顺序:1次查找留头,在去第二条支路上找到头;
1、python3新式类继承顺序:
a、2条支路通往1个头 python3中的类属于新式类,首次查找规则是广度优先(从左往右找)
MRO图:
继承顺序:
新式类:F-->D--->B(不会找到头留1个,去右边找E) | E--->C--->A--->object
经典类:F-->D-->B-->A--->E--->C
代码:
#新式类的继承,在查找属性时遵循广度优先 class A(object): def test(self): print('from A') class B(A): # def test(self): # print('from B') pass class C(A): def test(self): print('from C') pass class D(B): # def test(self): # print('from D') pass class E(C): def test(self): print('from E') class F(D,E): #注意多继承一定要遵循 MRO图顺序,不能先继承父类,还继承父类的子类 例:class F(A,B/C/D/E)都会报错 # def test(self): # print('from F') pass f1=F() f1.test() # F-->D--->B(不会找到头)留1个)--->E--->C--->A--->object 广度优先
b、如果3条支路通往1个头
MRO图:
继承顺序:
新式类:H-->E--->B-->F-->C-->G-->D-->A
经典类:H-->E-->B-->A-->F-->C-->G--D
代码:
class A(object): def test(self): print('from A') pass class B(A): # def test(self): # print('from B') pass class C(A): # def test(self): # print('from C') pass class D(A): # def test(self): # print('from D') pass class E(B): # def test(self): # print('from E') pass class F(C): # def test(self): # print('from F') pass class G(D): # def test(self): # print('from G') pass class H(E,F,G): # def test(self): # print('from H') pass h1=H() h1.test()
c、如果有2条之路就意味着有2个源头,支路1到头,支路2到头
MRO图:
继承顺序:
新式类: F-->D--->B-->X(走到头) | E--->C--->C--->Y--->object(走到头)
经典类: F-->D--->B-->X(走到头) | E--->C--->C--->Y--->object(走到头)
代码:
class X(object): def test(self): print('from X') pass class Y(object): def test(self): print('from Y') pass class B(X): # def test(self): # print('from B') pass class C(Y): def test(self): print('from C') pass class D(B): # def test(self): # print('from D') pass class E(C): def test(self): print('from D') pass class F(D,E): # def test(self): # print('from F') pass f1=F() f1.test()
三、继承关系混乱不遵循CRO
注意多继承一定要遵循 MRO图顺序,不能先继承父类,还继承父类的子类 例:class F(A,B/C/D/E)都会报错
四、self是到底谁?
为什么B类中没有f2方法却可以执行呢,一定要明白self对象是谁的实例?
obj对象没有f1方法,就去self对象对应的类开始找
obj对象没有f2方法,也去self对象对应的类开始找
class A(object): def f2(self): print('A.f2') class B(object): def f1(self): print('B.f1') self.f2() #为什么B类中没有f2方法却可以执行呢,一定要明白self对象是谁的实例? #obj对象没有f1方法,就去self对象对应的类开始找 #obj对象没有f2方法,也去self对象对应的类开始找 class C(A): def f1(self): print('C.f1') class D(B): def f2(self): print('D.f1') class Foo(A,D): pass obj=Foo() obj.f1() #执行结果 # B.f1 # A.f2