zoukankan      html  css  js  c++  java
  • 25 继承 多继承 组合 菱形继承 接口 鸭子类型

    1.继承的另一种使用方式  
    实现一个存储类 在提供基本的存取功能之外 还要可以限制存储元素的类型

    最常见的是直接继承一个已经存在的类

    当你想要创建一个新的类 发现这个类中的一些 在某一个类中已经存在

    那就没有必要从头开始写 ,可以直接继承已有的类 然后做补充
    class School(list):
    def __init__(self, element_cls):
    # 当你覆盖了init方法时
    # 不要忘记调用super().init函数让父类完成原有的初始化操作
    super().__init__()
    self.element_cls = element_cls

    def append(self, obj):
    # if isinstance(object,str) # 判断要存储的元素是否是指定类型

    if obj.__class__ == self.element_cls:
    super().append(obj)
    else:
    print('只能是%s' % self.element_cls.__name__)

    # self.element_cls(__name__)


    l = School(str)
    l.append(12)
    l.append('147')
    print(l)

    # 多继承
    class A:
    def test(self):
    print('from a')
    super().test()
    class B:
    def test(self):
    print('from b')
    pass

    class C(A,B):
    pass

    c=C()
    c.test()
    print(C.mro())

    # 当你使用super()函数时,
    # Python会在MRO列表上继续搜索下一个类。
    # 只要每个重定义的方法统一使用super()并只调用它一次
    # ,那么控制流最终会遍历完整个MRO列表,
    # 每个方法也只会被调用一次

    # 注意:使用super调用的所有属性,

    # 都是从MRO列表当前的位置往后找,
    # 千万不要通过看代码去找继承关系,一定要看MRO列表)

    # 例子
    class A():
    # q=3
    pass

    class B(A):
    # q=5
    pass

    class C(A):
    q=9
    pass

    class D(B,C):
    # q=15
    pass

    Q=D()
    print(Q.q)
    print(D.mro())

    组合:
    指的是 一个类把另一个类的对象作为自己的属性 就称之为组合
    当你定义一个类 并且这个类拥有某种类型的属性时 就称之为组合

    都是用用来重用代码的方式:
    组合描述的是 什么拥有什么的关系 学生 有 书 学生有手机
    基础描述的是 什么是什么的关系 麦兜是猪 猪猪侠也是猪
    class Person:
    def __init__(self, name):
    self.name = name


    p = Person('perry')
    print(p.name)

    '''例子'''

    class PC:
    def open_app(self, app_name):
    print('open %s' % app_name)


    class Student:
    def __init__(self, PC, notebook):
    self.PC = PC
    self.notebook = notebook

    pass

    qw=PC()
    notebook=PC()

    st=Student(qw,notebook)
    st.notebook.open_app('学电脑')
    菱形继承
    # 在py2中 A就是一个经典类
    class A:
    pass

    # 如果你的代码需要兼容py2 那应该显式的继承object 无论是直接还是间接继承

    class B(obj):
    pass

    class A(B):
    pass
    经典类与新式类
    1.只有在python2中才分新式类和经典类,python3中统一都是新式类
    2.在python2中,没有显式的继承object类的类,以及该类的子类,都是经典类
    3.在python2中,显式地声明继承object的类,以及该类的子类,都是新式类
    3.在python3中,无论是否继承object,都默认继承object,即python3中所有类均为新式



    经典类:
      深度优先
    新式类:
        先深度 直到有一个公共父类时,查找其他路线(基于C3算法)

    接口

    接口就是一套协议规范
    具体表现形式: 有一堆函数 但是只明确了函数的名称 没有明确函数具体实现
    class USB:

    def open(self):
    pass

    def close(self):
    pass

    def work(self):
    pass
    使用接口可以提高程序的扩展性

    只要对象按照接口规定方法来实现,使用者就可以无差别使用所有对象

    接口与抽象类
    抽象:
      指的是不清楚,不具体,看不懂的
    抽象方法
      指的是 没有函数体的方法 用@abc.abstractmethod 装饰器
      如果类中具备抽象方法 那么这个类就称之为抽象类 
    抽象类的特点:

    ​ 不能直接实例化 必须有子类覆盖了所有抽象方法后才能实例化子类
    接口的区别:

    ​ 接口是指只有方法声明而没有实现体 , 接口中所有方法都是抽象的

    import abc

    class Test(metaclass= abc.ABCMeta):

    @abc.abstractmethod
    def say_hi(self):
    pass

    class QW(Test):
    def say_hi(self):
    print('是 QW ')

    q=QW()
    q.say_hi()
    如果接口的子类没有实现接口中的方法,那是没有任何意义的 

    抽象类之所以出现的意义:通过抽象类来强行限制子类必须覆盖所有的抽象方法
    鸭子类型

    说如果一个对象叫声像鸭子,走路像鸭子,长得像鸭子,那它就是鸭子 

    是python 推荐的方式,python不喜欢强行限制你
    利用标准库中定义的各种‘与文件类似’的对象,尽管这些对象的工作方式像文件,但他们没有继承内置文件对象的方法
    class PC():

    def content_device(self,usb_device):
    usb_device.open()
    usb_device.work()
    usb_device.close()

    class Mouse:
    # 实现接口规定的所有功能
    def open(self):
    print('mouse open')
    def work(self):
    print('mouse work')
    def close(self):
    print('mouse close')

    mouse=Mouse()
    pc=PC()

    pc.content_device(mouse)

    class KeyBoard:
    def open(self):
    print('KeyBoard open')

    def work(self):
    print('KeyBoard work')

    def close(self):
    print('KeyBoard close')

    key=KeyBoard()

    pc.content_device(key)

      






  • 相关阅读:
    socket套接字
    网络编程
    元类,反射
    元类的多态、内置函数、魔法函数
    接口和抽象类
    面对对象之精髓——封装
    面对对象之继承、组合等
    Ubuntu 与 VM命令
    VM虚拟机修改 [ ubuntu ] sources 源 巴巴云镜像安装 python
    创建进程
  • 原文地址:https://www.cnblogs.com/komorebi/p/10883413.html
Copyright © 2011-2022 走看看