## 继承父类,并拓展新功能supper(): ```python class MyList(list): def __init__(self,element_cls): # 当你覆盖了init方法时 # 不要忘记调用super().init函数让父类完成原有的初始化操作 super().__init__() self.element_cls = element_cls def append(self, object):#覆盖父类 # if isinstance(object,str) # 判断要存储的元素是否是指定类型 if object.__class__ == self.element_cls: super().append(object) else: print("只能存储%s类型!" %self.element_cls.__name__) ``` 多继承问题:属性/方法查找顺序 ```python 问题:多继承时如果多个父类中出现了同名的属性/函数 # 你不能用眼睛去判断查找顺序 ,需要使用mro列表来查看真正的继承顺序 # 总结super在访问父类属性时 是按照mro列表一层层往上找的 mro:[<class '__main__.E'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.A'>, <class 'object'>] ``` ## 什么是组合: ```python 组合: 指的是 一个类把另一个类的对象作为自己的属性 就称之为组合 无处不在 当你定义一个类 并且这个类拥有某种类型的属性时 就称之为组合 继承的逻辑是,什么是什么 组合的逻辑是:什么有什么(功能) ``` ## 菱形继承: ```python 菱形继承:一个子类有多个父类,每个父类的最终的父类又是同一个类.即是菱形继承.如果最终的父类是object类,那他是新式类.如果最终的类不是object,那么是经典类. # 在py2中 A就是一个经典类,在py2中继承object,需要再括号内表明. # class A: # pass 经典类属性/方法的访问顺序是:深度优先,先贯穿第一个父类的逐级访问,再开始访问第二个父类. 新式类:属性/方法的访问顺序:先深度再宽度.先按第一个父类逐级访问到object的第一个子类.然后开始访问第二个父类,知道最后一个父类贯穿访问到最终的object. ``` ## 抽象类 ```python 拥有抽象方法的类就是抽象类.(只要有一个抽象方法,即为抽象类) 抽象方法:没有函数体的方法 #抽象类的特点:不能直接被实例化! #定义抽象类,需要三个组成部分: 1.导入import abc 模块 , 2.继承abc中的:(metaclass=abc.ABCMeta)父类, 3,在抽象方法前加装饰器:@abc.abcstractmethod ``` ## 接口 ```python 接口就是一套协议规范 具体表现形式:有一堆函数,但是只明确了函数的名称 没有明确函数具体实现 #所以,接口属于抽象类.接口中的方法都是抽象方法! #接口中的抽象方法的目的,规范子类在继承时,必须重新覆盖接口中的抽象方法,以完成规定功能,否则无法实例化! import abc class USB(metaclass=abc.ABCMeta): @abc.abstractmethod def open(self): pass @abc.abstractmethod def close(self): pass @abc.abstractmethod def work(self): pass ``` ## 鸭子类型 ```python 根据python的语言特点,对接口的规范的放宽 # 如果key1的特征和行为都像USB设备 那就把它当做USB设备来使用 # 对于使用者而言可以不用关心这个对象是什么类,是如如何是实现, 总结:如果 实例对象 的属性/方法都像规范的要求,那么就把他拿来作为属性,执行另一个实例化的对象,来操作它. 问题:到底有多像,才能无误执行??? ```