• Python面向对象之继承


    前言:

    继承是面向对象的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
  • 相关阅读:
    python学习之控制语句
    linux中的网络基础
    python学习之准备
    linux用户权限
    python学习之函数和函数参数
    python学习之输出与文件读写
    linux中的vim编辑器的使用
    从产品和用户角度,思考需求和用户体验
    好记性不如烂笔头
    TI DaVinci(达芬奇)入门
  • 原文地址:https://www.cnblogs.com/sss4/p/7717588.html
Copyright © 2020-2023  润新知