1. 程式人生 > >python之繼承中組合用法與菱形繼承關係查詢法

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.如果對下一個類存在兩個合法的選擇,選擇第一個父類