之前的文章《Python面向对象教程之单继承》介绍了Python的单继承的知识,今天接着介绍面向继承的第二个重要知识:多继承。
所谓的单继承指的是子类只继承一个基类,但实际应用中有可能需要继承多个类的情况,即多继承。联想一下现实生活,一个孩子会继承父亲的某些特征,同时也会继承母亲的特征,多继承的概念便不难理解了。
接下来的部分同样基于这样的逻辑进行讲解,需要注意的是,上述的“孩子”作为以下代码中的“子类”,“父亲”作为“第一个基类”,“母亲”作为“第二个基类”,先给出类的定义:
# 第一个基类的定义
class Father():
def __init__(self, name, weight): # 构造函数
print('father的init开始被调用')
self.name = name # 属性,代表名字
self.weight= weight # 属性,代表体重
print('father的init结束被调用')
# 第二个基类的定义
class Mother():
def __init__(self, name, height): # 构造函数
print('mother的init开始被调用')
self.name = name + "'s wife" # 属性,代表名字,注意和上面不一样
self.height = height # 属性,代表身高
print('mother的init结束被调用')
# 子类的定义,继承顺序是先Father后Mother,分别继承weight和height属性
class Son1(Father, Mother): # 括号里都写上要继承的类
def __init__(self, name, weight, height):
print('Son1的init开始被调用')
Father.__init__(self, name, weight) # 调用第一个基类的构造函数
Mother.__init__(self, name, height) # 调用第二个基类的构造函数
print('Son1的init结束被调用')
接着利用python内置函数__mro__来展示搜索顺序:
>>> print(Son1.__mro__)
(, , , )
不难看出调用基类的顺序是先是Father再是Mother。
继续看看实例化会发生什么:
>>> s1 = Son1('Jordan', 60, 172)
Son1的init开始被调用
father的init开始被调用
father的init结束被调用
mother的init开始被调用
mother的init结束被调用
Son1的init结束被调用
为什么实例化时就会输出这么多信息呢?原因在于构造函数在对象生成的时候会自动被调用。而且,从输出的信息可以明显地看出调用两个基类的顺序:先father再mother。
继续看看接下来会输出什么结果:
>>> print('姓名:', s1.name)
姓名:Jordan's wife
>>> print('体重:', s1.weight)
体重:60
>>> print('身高:', s1.height)
身高:172
后面的结果是显而易见的,可是为什么输出的姓名是“Jordan's wife”呢?一开始的结果不是一直在说明调用基类的顺序是先father后mother吗?其实,原因便在于下面的代码,因为基类Mother对name属性进行重新设置,原本由基类Father设置的是“Jordan”变成了“Jordan's wife”,所以在多继承的时候要小心同一属性的重复设置。
Father.__init__(self, name, weight) # 此时name是Jordan
Mother.__init__(self, name, height) # 此时name变成了Jordan's wife
好了,关于多继承就先介绍到这了,其实多继承还有更多需要注意的地方,限于篇幅,有机会本公众号会继续讲解。
本文转自微信公众号:superdiao的果壳
喜欢的朋友可以去关注(关注后有福利哦~),记得先给本文点赞或者点喜欢呐!