• 多继承 , 组合 , 菱形继承 , 接口 , 抽象 , 鸭子类型


    一, 复习

    属性的的正确存放位置:
        类中应该存储所有对象公共的内容
        对象中存储都是每个对象独有的(都不同)
    初始化函数:
        给对象的属性赋初值 , 可以保证只要对象被创建就一定有相应的属性
        节省了重复代码
    
    绑定方法:
        指的是 将类或对象与函数进行了绑定
        之所以绑定是为了提高整合度,后续在拿到对象就可以直接调用而无需关心 数据是什么 如何处理
        对象也可以看做是一个存储数据的容器
    
        对象绑定方法:
            默认情况下就是绑定给对象的
            当执行该方法时,需要访问对象中的内容
            当使用对象调用时 会自动传入对象本身作为第一个参数
            用类来调用时就是一个普通函数  该怎么传就这么传
        类绑定方法:
            当执行该方法时,需要访问类中的内容而不需要对象中的内容
            @classmethod
            无论使用类还是对象来调用都会自动传入类本身作为第一个参数
        非绑定方法
            既不需要访问类中的内容 也不需要访问对象中的内容  那就作为非绑定方法  就是一个普通函数  没有自动传值的效果
            @staticmethod
    
    继承
        说的是类与类之间的关系
        存在基础关系后 子类可以直接使用父类已经存在的内容   总的来说是为了提高代码的复用性
        例如猫 和狗 都属于动物类
        描述的时 什么是什么的关系  如:猫是动物
    
        要开始累积自己的类库 把经常使用的小功能写到一个模块中  以后可以直接调用
    
        class 子类(父类):
            pass
    
    属性查找顺序
        对象本身 -> 所在的类 -> 类的父类 -> .... object
    
    抽象
        使用基础时 应该先抽象 在继承
        抽象指的是 把一系列类中的相同的特征和行为抽取 形成一个新的类 (公共父类)
    
    派生
        子类拥有与父类不同的内容
    覆盖
        子类出现了与父类完全相同的名字
    
    一切皆对象
        在py3里面所有东西全是对象  包括 int list 模块 函数 .....包等等....
        list.append(li,1)
    
    
    子类访问父类的内容
        1.指名道姓 直接写死了类名   即时不存在继承关系也能调用
        2.super().要访问的属性 (py3出现的)
        3.super(这个子类的名字,self).属性

    二 , 继承已有的类来扩展新功能


    #
    实现一个存储类,在提供基本的存取功能之外,还要可以限制存储元素的类型 class MyList(list): def __init__(self,element_cls): #当你覆盖了init时,不要忘记调用super().init函数让父类完成原有的初始化操作 super().__init__() self.element_cls = element_cls def append(self,object): if object.__class__ == self.element_cls: #如果传进来的数据与我限制的的类型匹配上,则添加到列表 super().append(object) else: print('只能存储%s类型!'%self.element_cls.__name__) li = MyList(str) li.append(10) #只能存储str类型! li.append('123') print(li) #['123']

    三 , 多继承问题

    class A:
        def test(self):
            print('from A')
            super().test()      #应该报错,但是执行成功了
    
    class B:
        def test(self):
            print('from B')
    
    
    class C(A,B):
        pass
    
    c = C()
    c.test()
    # from A
    # from B
    
    print(C.mro())  #[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
    
    #问题:多继承时如果多个父类中出现了同名的属性/函数
    #你不能用眼睛去判断查找顺序,需要使用mro列表去查看真正的继承顺序
    #总结:super在访问父类属性时,是按照mro列表一层层往上找的
    
    class A:
        a = 1
        pass
    
    class B(A):
        a = 2
        pass
    
    class C(A):
        a = 3
        pass
    
    class D(A):
        a = 4
        pass
    
    class E(B,C,D):
        a = 5
        pass
    
    aa = E()
    print(aa.a)
    print(E.mro())  #[<class '__main__.E'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.A'>, <class 'object'>]

    四  , 组合

    '''
    组合:
        指的是一个类把另一个类作为自己的属性来使用,就称之为组合
        当你定义一个类,并且这个类拥有某种类型的属性时,就称之为组合
        
    组合描述的是:什么拥有什么的关系,  学生有书  学生有手机
    继承描述的是:什么是什么的关系   麦兜是猪  猪猪侠也是猪
    '''''
    
    class PC:
        def open_app(self,app_name):
            print('open %s'% app_name)
    
    class Student:
        def __init__(self,PC,notbook):
            self.PC = PC
            self.notbook = notbook
    
    
    pc = PC()
    notbook = PC()
    
    s = Student(pc,notbook)
    s.PC.open_app('qq')
    s.notbook.open_app('what')
    # s.PC.open_app('ch')

    五 , 菱形继承

    # 在py2中 A就是一个经典类
    # class A:
    #     pass
    
    # 如果你的代码需要兼容py2 那应该显式的继承object  无论是直接还是间接继承
    class B(object):
        pass
    
    class A(B):
        pass

    六 , 接口

    '''
    接口:就是一套协议规范
    具体表现形式:有一堆函数,但是只明确了函数的名称,没有明确函数的具体表现
    '''''
    
    import  abc
    
    class USB(metaclass=abc.ABCMeta):
        @abc.abstractmethod
        def open(self):
            pass
        @abc.abstractmethod
        def work(self):
            pass
        @abc.abstractmethod
        def close(self):
            pass
    
    
    class Mouse(USB):
        #实现接口规定的所有功能
        def open(self):
            print('mouse open')
    
        def work(self):
            print('mouse word')
    
        def close(self):
            print('mouse close')
    
    class KeyBord:
        def open(self):
            print('KeyBoard open')
    
        def work(self):
            print("KeyBoard working...")
    
        def close(self):
            print("KeyBoard closed")
    #问题是无法限制子类,必须真正的实现接口中的功能 class Camera(USB): def open(self): pass def work(self): pass def close(self): pass class PC: def device(self,usb_device): usb_device.open() usb_device.work() usb_device.close() #在实例化Camera abc模块就会检查Camera是否实现了所有的抽象方法,如果没有则无法实例化 c = Camera() p = PC() #创建一个鼠标设备 m = Mouse() #创建一个键盘设备 key1 = KeyBord() #链接到电脑上 p.device(m) p.device(key1) p.device(c)

     

    七 , 抽象

    '''
    抽象类:具备抽象方法的类
    抽象方法是,没有函数体的方法
    抽象类的特点:不能直接实例化
    '''''
    
    import abc
    class Test(metaclass=abc.ABCMeta):
    
        @abc.abstractmethod
        def say_hi(self):
            pass
    
        #可以有普通函数
        def info(self):
            print('my class is Test')
    
    class TT(Test):
        def say_hi(self):
            print('i an TT obj')
        # pass
    
    
    t = TT()
    t.info()
    t.say_hi()

    八 , 鸭子类型

    class PC():
    
        def conntent_device(self, usb_device):
            usb_device.open()
            usb_device.work()
            usb_device.close()
    
    
    class Mouse:
        # 实现接口规定的所有功能
        def open(self):
            print("mouse opened")
    
        def work(self):
            print("mouse working...")
    
        def close(self):
            print("mouse closed")
    
    mouse = Mouse()
    pc = PC()
    
    pc.conntent_device(mouse)
    
    
    
    class KeyBoard:
        def open(self):
            print("KeyBoard opened")
    
        def work(self):
            print("KeyBoard working...")
    
        def close(self):
            print("KeyBoard closed")
    
    key1 = KeyBoard()
    
    # 如果key1的特征和行为都像USB设备 那就把它当做USB设备来使用
    # 对于使用者而言可以不用关心这个对象是什么类,是如如何是实现,
    pc.conntent_device(key1)
    class Linux:
        def read_data(self,device):
            data = device.read()
            return data
    
        def write_data(self,device,data):
            device.write(data)
    
    class Disk:
        def read(self):
            print("disk reading....")
            return "这是一个磁盘上的数据"
    
        def write(self,data):
            print("disk writing %s..." % data)
    
    class UP:
        def read(self):
            print("disk reading....")
            return "这是一个U盘上的数据"
    
        def write(self,data):
            print("disk writing %s..." % data)
    
    
    l = Linux()
    
    
    d = Disk()
    data = l.read_data(d)
    l.write_data(d,"这是一个数据....")
    
    
    up1 = UP()
    l.read_data(up1)
    l.write_data(up1,"一个数据...")

  • 相关阅读:
    Android WIFI 启动流程(TIP^^)
    MVVM模式原则
    CoreData入门
    转:iOS绘制一个UIView
    CGBitmapContextCreate函数参数详解
    RACCommand
    ReactiveCocoa内存管理
    IOS TableView滑动不灵敏问题
    IOS数组的排序和筛选
    IOS取消performSelector警告
  • 原文地址:https://www.cnblogs.com/HZLS/p/10895830.html
Copyright © 2020-2023  润新知