python之继承中组合用法与菱形继承关系查找法
1.什么是组合
组合就是一个类的对象具备某一属性,该属性的值是指向另外外一个类的对象
2.为什么用组合
组合也是用来解决类与类之间代码冗余问题
3.用法
class Course: #组合
def __init__(self, name, period, price):
self.name = name
self.period = period
self.price = price
def tell_info(self):
msg = """
课程名:%s
课程周期:%s
课程价钱:%s
""" % (self.name, self.period, self.price)
print(msg)
class OldboyPeople: #父类
school = 'oldboy'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
class OldboyStudent(OldboyPeople): 子类
def __init__(self, name, age, sex, stu_id):
OldboyPeople.__init__(self, name, age, sex)
self.stu_id = stu_id
def choose_course(self):
print('%s is choosing course' % self.name)
class OldboyTeacher(OldboyPeople): #子类
def __init__(self, name, age, sex, level):
OldboyPeople.__init__(self, name, age, sex)
self.level = level
def score(self, stu, num):
stu.score = num
print('老师[%s]为学生[%s]打分[%s]' % (self.name, stu.name, num))
# 创造课程
python = Course('python全栈开发', '5mons', 3000)
linux = Course('linux运维', '5mons', 800)
# python.tell_info()
# linux.tell_info()
# 创造学生与老师
stu1 = OldboyStudent('猪哥', 19, 'male', 1)
tea1 = OldboyTeacher('egon', 18, 'male', 10)
# 将学生、老师与课程对象关联/组合
stu1.course = python #把课程python对象内存地址添加到stu1对象名称空间中,之后可以直接调用到course中的函数
print(stu1.__dict__)
tea1.course = linux
stu1.course.tell_info() 直接用绑定方法调用组合里面的函数属性
tea1.course.tell_info()
二.菱形继承关系查找法
1.菱形继承
当一个子类继承多个父类时,多个父类最终继承了同一个类,称之为菱形继承
2.菱形继承的问题:
python2区分经典类与新式类,如果子类继承的是一个菱形继承,那么经典类与新式类的区别是:
经典类下查找属性为:深度优先查找(先一条道走到底,在找别的父类)
新式类下查找属性为:广度优先查找(先每条道的找,最后一条道就查找到底)
python2中经典类
python3中新式类
继承原理:
python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,例如
__mro__查看继承查找
class A(object):
def test(self):
print('from A')
class B(A):
def test(self):
print('from B')
class C(A):
def test(self):
print('from C')
class D(B):
def test(self):
print('from D')
class E(C):
def test(self):
print('from E')
class F(D,E):
# def test(self):
# print('from F')
pass
f1=F()
f1.test()
print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性
#新式类继承顺序:F->D->B->E->C->A
#经典类继承顺序:F->D->B->A->E->C
#python3中统一都是新式类
#pyhon2中才分新式类与经典类
继承顺序
>>> 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列表并遵循如下三条准则:
1.子类会先于父类被检查
2.多个父类会根据它们在列表中的顺序被检查
3.如果对下一个类存在两个合法的选择,选择第一个父类