• python面向对象-继承


    (一)单继承

    在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类或派生类(Subclass),而被继承的class称为父类或基类(Base class、Super class)。

    比如,我们已经编写了一个名为Animal的class,有一个eat()方法可以直接打印:

    1 class Animal(object):
    2     def eat(self):
    3         print("Animal is eating")

    当我们需要编写Dog或Cat类时,就可以直接从Animal类继承:

    1 class Dog(Animal):
    2     pass
    3 
    4 
    5 class Cat(Animal):
    6     pass

    对于Dog来说,Animal就是它的父类,对于Animal来说,Dog就是它的子类。Cat和Dog类似。

    继承有什么好处?最大的好处是子类获得了父类的全部功能。由于Animial实现了eat()方法,因此,Dog和Cat作为它的子类,什么事也没干,就自动拥有了eat()方法:

    1 d1 = Dog()
    2 d1.eat()
    3 
    4 c1 = Cat()
    5 c1.eat()

    运行结果如下:

    1 Animal is eating
    2 Animal is eating

    当然,也可以对子类增加一些方法,比如Dog类:

    1 class Dog(Animal):
    2     def eat(self):
    3         print("Dog is eating meat")
    4         
    5     def bark(self):
    6         print("Dog is barking")

    当子类和父类都存在相同的eat()方法时,我们说,子类的eat()覆盖了父类的eat(),在代码运行的时候,总是会调用子类的eat()。这样,我们就获得了继承的另一个好处:多态。我们可以理解为子类把父类的代码复制到了自己里面

    此时 d1.eat() 的输出是: Dog is eating meat 

    我们再添加一个Hasky类继承Dog类,

    1 class Hasky(Dog):
    2     pass

    当Hasky类的实例调用eat方法时,

    1 h1 = Hasky()
    2 h1.eat()

    寻找eat方法遵循自下而上的顺序(我们把继承关系看成一颗倒立的树),因此运行结果是: Dog is eating meat 

    (二)多继承

     Python中允许一个类同时继承多个类,那么在阅读别人写的代码时就遇到一个问题,有时一个方法在多个类中都有实现,我们如何寻找正确的实现呢?

    (1)首先看一个简单的例子,C1同时继承C2,C3:

     1 class C3(object):
     2     def f1(self):
     3         print("C3.f1")
     4 
     5 
     6 class C2(object):
     7     def f1(self):
     8         print("C2.f1")
     9 
    10 
    11 class C1(C2, C3):
    12     pass
    13 
    14 obj_c1 = C1()
    15 obj_c1.f1()

    Python在寻找f1的实现时遵循从左至右的原则(选在C2里找,然后在C3里):

    因此程序运行结果是: C2.f1 

    (2)我们再来看一个稍微复杂的例子,加入上例中C2还继承了一个C4类,而C3与C4对同一个方法f2都有实现,Python如何处理呢?

     1 class C4(object):
     2     def f2(self):
     3         print("C4.f2")
     4 
     5 
     6 class C3(object):
     7     def f1(self):
     8         print("C3.f1")
     9 
    10     def f2(self):
    11         print("C3.f2")
    12 
    13 
    14 class C2(C4):
    15     def f1(self):
    16         print("C2.f1")
    17 
    18 
    19 class C1(C2, C3):
    20     pass
    21 
    22 obj_c1 = C1()
    23 obj_c1.f2()

    按照上面的例1,Python首先在C2里寻找,而C2没有f2方法,这时有两条路,往上找C4,或者往右找C3,

    从实际运行结果看,Python遵循深度优先原则,如下图所示:

    程序运行结果: C4.f2 

    (3)我们再看一个相对复杂的例子,类继承关系如下图:

     

    假如C5和C3里都有一个f3方法,代码如下:

     1 class C5(object):
     2     def f3(self):
     3         print("C5.f3")
     4 
     5 
     6 class C4(C5):
     7     def f2(self):
     8         print("C4.f2")
     9 
    10 
    11 class C3(C5):
    12     def f1(self):
    13         print("C3.f1")
    14 
    15     def f2(self):
    16         print("C3.f2")
    17 
    18     def f3(self):
    19         print("C3.f3")
    20 
    21 
    22 class C2(C4):
    23     def f1(self):
    24         print("C2.f1")
    25 
    26 
    27 class C1(C2, C3):
    28     pass
    29 
    30 obj_c1 = C1()
    31 obj_c1.f3()

    那么obj_c1.f3()会使用哪个类的f3呢?按照我们在例2中深度优先的原则,应该是C5的f3,可是程序运行结果却是 C3.f3 

    这里有一个原因,当C4和C3有共同父类时,父类里是最后才寻找的。实际搜寻顺序如下图的数字:

  • 相关阅读:
    装饰器
    FLASK
    Flask第一个实例
    各种各样的PyQt测试和例子
    项目实战:天气信息查询
    窗口设置、QSS
    槽和信号
    布局
    打印机
    菜单栏、工具栏、状态栏
  • 原文地址:https://www.cnblogs.com/z-joshua/p/6378828.html
Copyright © 2020-2023  润新知