前言:

继承是面向对象的3大特性之一,对于继承一点要注意一下4点。

 

一、基本查找

如果子类继承了父类,子类的实例化对象,没有的方法和属性会去父类找

class Parent(object): #父类
    def f1(self):
        print('f1')

class Sub(Parent): #子类
    pass

obj=Sub()      #如果子类继承了父类,子类的实例化对象,没有的方法和属性会去父类BAR()
obj.f1()
View Code

 

二、多继承查找顺序

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  广度优先
View Code

 

 

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()
View Code

 

 

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()
View Code

 

 

 

三、继承关系混乱不遵循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
View Code

 

posted on 2017-10-23 16:41  Martin8866  阅读(1631)  评论(0编辑  收藏  举报