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

    一, 复习

    属性的的正确存放位置:
        类中应该存储所有对象公共的内容
        对象中存储都是每个对象独有的(都不同)
    初始化函数:
        给对象的属性赋初值 , 可以保证只要对象被创建就一定有相应的属性
        节省了重复代码
    
    绑定方法:
        指的是 将类或对象与函数进行了绑定
        之所以绑定是为了提高整合度,后续在拿到对象就可以直接调用而无需关心 数据是什么 如何处理
        对象也可以看做是一个存储数据的容器
    
        对象绑定方法:
            默认情况下就是绑定给对象的
            当执行该方法时,需要访问对象中的内容
            当使用对象调用时 会自动传入对象本身作为第一个参数
            用类来调用时就是一个普通函数  该怎么传就这么传
        类绑定方法:
            当执行该方法时,需要访问类中的内容而不需要对象中的内容
            @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,"一个数据...")

  • 相关阅读:
    November 13th 2016 Week 47th Sunday The 1st Day
    November 12th 2016 Week 46th Saturday
    November 11th 2016 Week 46th Friday
    November 10th 2016 Week 46th Thursday
    November 9th 2016 Week 46th Wednesday
    November 8th 2016 Week 46th Tuesday
    windows 7文件共享方法
    Win7无线网络共享设置方法
    常量指针和指针常量
    如何查找局域网的外网ip
  • 原文地址:https://www.cnblogs.com/HZLS/p/10895830.html
Copyright © 2011-2022 走看看