python中的抽象类及多继承

一、抽象类

之前我们定义了Person类实现了eat()、sleep()方法,
每种人都会吃喝但是吃喝的地点不同,如果实现了方法体就浪费了。因此我们可以只定义eat()方法,不实现方法体,这种形式我们可以将方法定义为抽象方法,具有抽象方法的类就叫做抽象类。
抽象类是一个特殊的类,只能被继承,不能实例化,抽象类中可以有抽象方法和普通方法。

(1) .定义抽象类

定义抽象类需要导入 abc模块。
from abc import ABCMeta, abstractmethod

from abc import ABCMeta, abstractmethod


class Animal(metaclass=ABCMeta):

(2).定义抽象方法

抽象方法:只定义方法,不具体实现方法体。
在定义抽象方法时需要在前面加入:@abstractmethod
抽象方法不包含任何可实现的代码,因此其函数体通常使用pass。

    @abstractmethod
    def eat(self): pass

    @abstractmethod
    def sleep(self): pass

定义一个Animal抽象类,定义eat()、sleep()抽象方法,定义两个子类继承Animal抽象类。

from abc import ABCMeta, abstractmethod


class Animal(metaclass=ABCMeta):
    @abstractmethod
    def eat(self): pass

    @abstractmethod
    def sleep(self): pass

    def breathe(self):
        print('呼吸空气')


class Dog(Animal):
    def eat(self):
        print('吃骨头')

    def sleep(self):
        print('睡狗窝')


class Cat(Animal):
    def eat(self):
        print('吃鱼')

    def sleep(self):
        print('睡猫舍')


dog = Dog()
dog.eat()
dog.sleep()
dog.breathe()
cat = Cat()
cat.eat()
cat.sleep()
cat.breathe()

输出为:

吃骨头
睡狗窝
呼吸空气
吃鱼
睡猫舍
呼吸空气

二、多继承

一个子类可以继承多个父类,就是多继承,并且拥有所有父类的属性和方法。
例如 孩子会继承自己的父亲和母亲的特征。

1、 语法

class 子类名(父类名1,父类名2…) : pass

class A(object):
    def test1(self):
        print('A---test1')

    def test2(self):
        print('A---test2')

class B(object):
    def test3(self):
        print('B---test3')

    def test4(self):
        print('B---test4')

class C(A,B):
    pass


c=C()
c.test1()
c.test2()
c.test3()
c.test4()

输出为:

A---test1
A---test2
B---test3
B---test4

2、 多继承注意事项

如果子类和父类有相同的方法,就会调用子类中的方法。

如果不同的父类中存在着相同的方法名称,子类对象调用的时候会调用哪个父类中的方法呢? Python会根据 MRO(method resolution order) 方法解析顺序列表进行查找。
提示:开发时,需要避免这种容易产生混淆的情况!

如果父类之间存在同名的属性和方法,应尽量避免使用多继承。

class A(object):
    def test1(self):
        print('A---test1')

class B(object):
    def test1(self):
        print('B---test1')

class C(A,B):
    pass


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

输出为:

A---test1
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]

3、 继承原理(钻石继承)

python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,例如
为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止,而这个MRO列表的构造是通过一个C3线性化算法来实现的。
我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:
1.子类会先于父类被检查
2.多个父类会根据它们在列表中的顺序被检查
3.如果对下一个类存在两个合法的选择,选择第一个父类

在这里插入图片描述
注意:D类有两个选择,默认选择B类执行。
在Python2.3之前,MRO是基于深度优先算法的,自2.3开始使用C3算法广度优先,定义类时需要继承object,这样的类称为新式类,否则为旧式类

4、 多继承中super本质

不是直接查找父类,而是根据调用节点的广度优先顺序执行的。
创建A、B、C、D类,D类继承B,C类,B类继承A类,C类继承A类。在每个方法中都调用super().func()方法,查看执行顺序。

class A(object):
    def test(self):
        print(' A test')


class B(A):
    def test(self):
        super().test()
        print(' B test')


class C(A):
    def test(self):
        super().test()
        print(' C test')


class D(B, C):
    def test(self):
        super().test()
        print(' D test')


d = D()
d.test()
print(D.mro())

输出为:

 A test
 C test
 B test
 D test
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

猜你喜欢

转载自blog.csdn.net/weixin_44251004/article/details/86513566