Python Day25:继承父类并拓展新功能super()、多继承、组合、菱形继承、接口、鸭子类型

## 继承父类,并拓展新功能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设备来使用
# 对于使用者而言可以不用关心这个对象是什么类,是如如何是实现,

总结:如果 实例对象 的属性/方法都像规范的要求,那么就把他拿来作为属性,执行另一个实例化的对象,来操作它.
问题:到底有多像,才能无误执行???

```
原文地址:https://www.cnblogs.com/huhongpeng/p/10923047.html