python 继承和多态

1 继承

继承:子类继承父类。继承是一种创建新类的方式。


2 继承的顺序

  1. 因为python支持多继承,所以有时候不得不考虑继承的顺序。

  2. Python类如果继承多个类,寻找类的方法有两种,分别是:广度优先和深度优先。
    其中python3和python2中的新式类,采用的是广度优先。
    python2中的经典类,采用的是深度优先。

class A:
    def test(self):
        print("test from A")

class B(A):
    # def test(self):
    #     print("test from B")
    pass

class C(A):
    def test(self):
        print("test from C")

class D(B):
    # def test(self):
    #     print("test from D")
    pass

class E(C):
    def test(self):
        print("test from E")

class F(D,E):
    # def test(self):
    #     print("test from F")
    pass

f1=F()
f1.test()
#print(F.mro())

python3新式类的顺序为:F->D->B->E->C->A->object
python2经典类的顺序为:F->D->B->A->E->C


3 继承原理

python是如何实现继承的,当你写完class的定义(继承关系)以后,python会计算出一个MRO(Method Resolution Order 方法解析顺序)表,本质上就是一个保存着所有基类的线性关系顺序表。

>>>F.mro()  #F.__mro__
[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

注意:__mro__属性只有在新式类中才有。经典类是没有的

为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
而这个MRO列表的构造是通过一个C3线性化算法来实现的。MRO列表实际上就是合并所有父类的MRO列表并遵循如下三条准则:

  1. 子类先于父类被检查
  2. 多个父类会根据它们在列表中的顺序
  3. 如果下一个类存在两个合法的选择,选择第一个父类

4 子类调用父类的方法

  • 父类名.父类的方法()
    (严格来说,只能算是一个类调用另一个类中的函数。如果去掉继承关系,并不影响最后的结果)
class People:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex

    def walk(self):
        print("People is walking")

class Chinses(People):
    def __init__(self,name,age,sex):
        People.__init__(self,name,age,sex)

    def walk(self):
        People.walk(self)
        print("walk from Chinese")

c=Chinses("egg",20,None)
c.walk()

结果:

People is walking
walk from Chinese
  • super
    在python2中,必须写成super(本类名,self).__init__(...)
    在python3中,可以写成上述形式,也可写成super().__init__(...)

super()可以理解为父类的一个对象,super().__init__(...)也就是父类对象调用绑定方法。

class People:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex

    def walk(self):
        print("People is walking")

class Chinses(People):
    def __init__(self,name,age,sex):
        super(Chinses,self).__init__(name,age,sex)   #super(Chinses,self).__init__(name,age,sex)

    def walk(self):
        super().walk()
        print("walk from Chinese")

c=Chinses("egg",20,None)
c.walk()

结果:

People is walking
walk from Chinese

使用super调用的所有属性,都是从MRO列表当前的位置往后。


5 多态和多态性

5.1 多态

多态:就是一个事物的多个形态。如继承。
如 动物有多种形态,猪、狗、猫。

import abc
class Animal(metaclass=abc.ABCMeta):
    @abc.abstractclassmethod
    def run(self):
        pass

class Pig(Animal):
    def run(self):
        print("Pig is running")

class Dog(Animal):
    def run(self):
        print("Dog is running")

class Cat(Animal):
    def run(self):
        print("Cat is running")

5.2 多态性

5.2.1 什么是多态性

多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同的内容。

def func(animal):
    animal.run()

func(Pig())
func(Dog())
func(Cat())

结果:

Pig is running
Dog is running
Cat is running

总结:

  1. 多态性是“一个接口(函数func),多种实现”。
  2. 多态的概念是在定义时,多态性是在调用时。

5.2.2 多态的好处

其实python本身是支持多态的,这样处理的好处:

  1. 增加了程序的灵活性
    以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(animal)。
  2. 增加了程序的可扩展性
    只要后续写的类继承了Animal类,就都有run()函数。使用时调用func(animal),其他都不用改变。
原文地址:https://www.cnblogs.com/yangzhenwei123/p/6759306.html