zoukankan      html  css  js  c++  java
  • 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()













  • 相关阅读:
    有趣的F-String
    停止使用非版本控制的可执行代码
    Django ORM中,如何使用Count来关联对象的子集数量
    Django Tastypie: 贴士,技巧和故障排除
    我实在不懂Python的Asyncio
    使用Let's Encrypt为网站加入SSL证书
    [debug]记一次竞态更新bug的解决
    我的web聊天之---序章
    我的音乐盒子(nodejs7 + koa2 + vue + vuex + vue-router)
    装饰器 生成器 进阶
  • 原文地址:https://www.cnblogs.com/johnsonbug/p/12708027.html
Copyright © 2011-2022 走看看