其他文章:
Python 面向对象编程 OOP--01--类和实例的基本概念
Python 面向对象编程 OOP--02--类中的单下划线和双下划线 5 种情况
Python 面向对象编程 OOP--03--类的组合和派生
Python 面向对象编程 OOP--04--多重继承和方法解释顺序 MRO
Python 面向对象编程 OOP 05--类、实例和其他对象的内建函数
Python 面向对象编程 OOP--06--super() 是一个描述器类
Python 允许子类继承多个父类,这种特性就是多重继承。多重继承既扩大了子类的能力,又增加了困难,即如何让子类在不同的父类之间如何继承同名的属性和方法,总有个先后顺序,这就是方法解释顺序 MRO。
在早期 Python,例如 Python 2.2 之前,MRO 算法非常简单:深度优先,从左而由搜索。目前针对经典类,新的查询方法是广度优先,而不是深度优先。而新式类都是继承自 object,会出现菱形类继承机构,需要新建 MRO。
1. 经典类的多重继承
以下面的代码为例,这是一种比较简单的情况。
Teacher、Singer 都是 Man 的子类,SingerTeacher 是Teacher、Singer的子类。在使用 work 方法时候,直接使用了 SingerTeacher 类内的方法。但是查询 love 属性时候,因为 SingerTeacher 没有定义,是继承而来的,按照从左而由的广度搜索,先搜索了 Singer 类的初始化值,即 “Song”。
class Man():
'''
This class is used to describle human!
'''
def __init__(self,name,age):
self.name=name
self.age=age
self.love="self"
def work(self):
print("Now a man is working")
class Teacher(Man):
'''
This class is used to describle worker!
'''
def __init__(self,name,age):
# 调用父类的初始化方法 __init__
super().__init__(name,age)
self.love="Students"
#重新定义 work 方法,这是派生
def work(self):
print("Now a teacher is teaching!")
class Singer(Man):
'''
This class is used to describle singer!
'''
def __init__(self,name,age,country):
# 调用父类的初始化方法 __init__
super().__init__(name,age)
self.country=country
self.love="Song"
#重新定义 work 方法,这是派生
def work(self,song):
print("Now a singer is singing "+song+" !")
class SingerTeacher(Singer,Teacher):
'''
This class is used to describle singer tearcher!
'''
#重新定义 work 方法,这是派生
def work(self,song):
print("Now a singer tearcher is working !")
allen=SingerTeacher("allen",20,"China")
print("allen.name is ==>",allen.name)
print("allen.age is ==>",allen.age)
print("allen.country is ==>",allen.country)
# 使用的是 Singer 里面的 love 属性
print("allen.love is ==>",allen.love)
# 先在SingerTeacher 中搜索,再去父类中搜索 work方法。
allen.work("甜蜜蜜")
可以通过__mro__ 查询相关 MRO
2. 新式类的多重继承
新式类即 类名后面加了 object 的类。也可以通过__mro__ 查询相关 MRO。但是因为新式类中所有的类都是 object 的后代,这就出现一个菱形的问题。所以会需要一个新的 MRO。
################### 求点赞,求转发,求评论,求收藏!#####################