~~核心程式設計(五):物件導向——多繼承~~

吃夏天的西瓜發表於2019-07-17

進擊のpython


多繼承


多繼承?什麼是多繼承?就是繼承多個唄!

這多好理解啊!

怎麼叫多繼承呢?

孫悟空知道吧!

猴子吧!神仙吧!

強行操作是不是就是兩個父類!

那怎麼繼承?

你一個都會,兩個就不會了??

對吧,要學會類比啊!

# -*- coding: utf-8 -*-
# @Time    : 2019.07.16
# @Author  : 爪爪
# @Url     : https://www.cnblogs.com/jevious/

class Shenxian:
    print("我是神仙,法力無邊!")
    pass


class Monkey:
    print("我是猴子,我賊流弊!")
    pass


class Sunwukong(Monkey, Shenxian):
    pass

Sunwukong()
我是神仙,法力無邊!
我是猴子,我賊流弊!

這時候你就可以發現,我sunwukong這個類

就繼承了shenxian和monkey的屬性

當然,sunwukong也可以繼承他們的方法

# -*- coding: utf-8 -*-
# @Time    : 2019.07.17
# @Author  : 爪爪
# @Url     : https://www.cnblogs.com/jevious/

class Shenxian:
    def shen(self):
        print("我是神仙,法力無邊!")
        pass


class Monkey:
    def hou(self):
        print('我是猴子,我賊流弊!')
        pass


class Sunwukong(Shenxian, Monkey):
    def sun(self):
        print("齊!天!大!聖!")
        pass


s = Sunwukong()

~~核心程式設計(五):物件導向——多繼承~~

看,當我例項化之後呼叫方法的時候

來自父類的函式是不是也可以被呼叫


  • 繼承順序

    看著很簡單哈,但是不僅僅是這樣的哦

    你看啊,houzi是不是還可以繼承個動物類?

    動物類是不是還可以繼承生物類?

    生物類是不是還可以繼承……

    總之如果要是擴充來說有好多對吧!

    在研究這個問題之前

    是不是還應該有個問題沒被解決呢?

    就是要是我shenxian類和monkey類裡

    都有個eat方法,當我sunwukong呼叫的時候

    是用哪個?

    # -*- coding: utf-8 -*-
    # @Time    : 2019.07.17
    # @Author  : 爪爪
    # @Url     : https://www.cnblogs.com/jevious/
    
    class Shenxian:
        def shen(self):
            print("我是神仙,法力無邊!")
            pass
    
        def eat(self):
            print("神仙吃東西!")
    
    
    class Monkey:
        def hou(self):
            print('我是猴子,我賊流弊!')
            pass
    
        def eat(self):
            print("猴子吃東西!")
    
    
    class Sunwukong(Shenxian, Monkey):
        def sun(self):
            print("齊!天!大!聖!")
            pass
    
    
    s = Sunwukong()
    
    s.eat()
    

    ~~核心程式設計(五):物件導向——多繼承~~

    從提示可以看出來例項化的eat方法是來自shenxian的

    那到底是不是呢?

    執行一下!

    神仙吃東西!

    果然,執行的是shenxian裡面的eat方法

    所以說大概就有概念了,這個繼承啊

    是有順序的

    先繼承shenxian裡面的方法,再繼承monkey的方法

    重複的以前面的為準(shenxian在monkey前面)

    但是,你以為

    這就完事了?


    就像我剛才提到的那個問題

    如果是那種情況,繼承順序是什麼樣的呢?????

    # -*- coding: utf-8 -*-
    # @Time    : 2019.07.17
    # @Author  : 爪爪
    # @Url     : https://www.cnblogs.com/jevious/
    
    class Super_shenxian:
        def eat(self):
            print("超級神仙吃東西!")
    
        pass
    
    
    class Shenxian(Super_shenxian):
        def shen(self):
            print("我是神仙,法力無邊!")
            pass
    
        def eat(self):
            print("神仙吃東西!")
    
    
    class Shengwu:
        def eat(self):
            print("生物吃東西")
    
        pass
    
    
    class Monkey(Shengwu):
        def hou(self):
            print('我是猴子,我賊流弊!')
            pass
    
        def eat(self):
            print("猴子吃東西!")
    
    
    class Sunwukong(Monkey, Shenxian):
        def sun(self):
            print("齊!天!大!聖!")
            pass
    
    
    s = Sunwukong()
    
    s.eat()

    在執行之前,我們先來分析一下這個程式的繼承關係

    ~~核心程式設計(五):物件導向——多繼承~~

    是吧,是這樣的吧!沒問題吧

    那按照我們來想的

    是不是應該可以有兩種查詢方法

    sunwukong⇨monkey⇨shengwu⇨shenxian⇨super_shenxian

    這種查詢方法叫 深度優先

    sunwukong⇨monkey⇨shenxian⇨shengwu⇨super_shenxian

    這種查詢方法叫 廣度優先

    那我們的繼承遵循哪種呢?

    執行上方程式碼

    猴子吃東西!

    但是這也不能確定是深度還是廣度

    那如果shengwu有eat方法

    shenxian也有eat方法

    但是monkey沒有eat方法

    那我要是執行結果是“神仙吃東西”

    是不是就代表著是廣度優先?

    同理,我要是執行結果是“生物吃東西”

    是不是就代表著是深度優先?

    這個邏輯能理解吧

    那我們試一下

    # -*- coding: utf-8 -*-
    # @Time    : 2019.07.17
    # @Author  : 爪爪
    # @Url     : https://www.cnblogs.com/jevious/
    
    class Super_shenxian:
        def eat(self):
            print("超級神仙吃東西!")
    
        pass
    
    
    class Shenxian(Super_shenxian):
        def shen(self):
            print("我是神仙,法力無邊!")
            pass
    
        def eat(self):
            print("神仙吃東西!")
    
    
    class Shengwu:
        def eat(self):
            print("生物吃東西")
    
        pass
    
    
    class Monkey(Shengwu):
        def hou(self):
            print('我是猴子,我賊流弊!')
            pass
    
        # def eat(self):
        #     print("猴子吃東西!")
    
    
    class Sunwukong(Monkey, Shenxian):
        def sun(self):
            print("齊!天!大!聖!")
            pass
    
    
    s = Sunwukong()
    
    s.eat()
    

    執行結果是:

    生物吃東西

    那說明什麼?說明繼承是深度優先是吧!

    邏輯沒問題吧!

    你以為???這就結束了???


  • 真◇繼承順序

    在python中啊,類的寫法有兩種

    經典類:

    class A:
        pass

    新式類:

    class B(object):
        pass

    而python呢,又有兩種版本 2.x 和 3.x

    所以就出現了四種組合情況是吧!

    在2.x版本中,經典類採用的是深度優先,新式類採用的是廣度優先

    在3.x版本中,無論新式類還是經典類,都是按廣度優先查詢的

    在2.x中預設的都是經典類,只有顯示繼承了object才是新式類

    在3.x中預設的都是新式類,不必顯示繼承object

    等會???????????????

    剛才我們們實驗出來了,3.x版本是深度優先啊!

    怎麼你現在跟我說是廣度優先???????

    kidding me???????????????

    別罵人別罵人!聽我狡辯說啊!


    有沒有這種情況?

    我的super_shenxian 和 shengwu 的上面還有個爹

    shijie!

    可以不!

    shijie裡面也有eat方法行不

    我把houzi的eat取消掉

    我再把shengwu的eat取消掉

    那我查詢的時候是不是應該繼續找shengwu的父親

    也就是shijie!

    然後執行shijie裡面的eat是吧

    最後列印”世界吃東西“是吧

    這是我們們原先的邏輯,沒問題吧!

    寫一下行吧

    # -*- coding: utf-8 -*-
    # @Time    : 2019.07.17
    # @Author  : 爪爪
    # @Url     : https://www.cnblogs.com/jevious/
    
    class Shijie(object):
        def eat(self):
            print("世界都在吃東西!")
    
        pass
    
    
    class Super_shenxian(Shijie):
        def eat(self):
            print("超級神仙吃東西!")
    
        pass
    
    
    class Shenxian(Super_shenxian):
        def eat(self):
            print("神仙吃東西!")
    
    
    class Shengwu(Shijie):
        # def eat(self):
        #     print("生物吃東西")
    
        pass
    
    
    class Monkey(Shengwu):
        # def eat(self):
        #     print("猴子吃東西!")
        pass
    
    
    class Sunwukong(Monkey, Shenxian):
        def sun(self):
            print("齊!天!大!聖!")
            pass
    
    
    s = Sunwukong()
    
    s.eat()
    

    你列印出來的是什麼??大聲告訴我!

    是不是”世界吃東西“?

    不是!

    是什麼?

    神仙吃東西!

    是不是就不是深度優先原則了????

    那他到底是什麼優先呢???????

    其實好多都在說是廣度優先

    但是很明顯,當沒有交集的時候,依照的是的是深度優先

    有交集又用的是類廣度有限的演算法

    那到底是什麼!!!!!!!!!!!!!


  • 多繼承C3演算法

    上面的都算簡單的,來來來,看看這個?

    # -*- coding: utf-8 -*-
    # @Time    : 2019.07.17
    # @Author  : 爪爪
    # @Url     : https://www.cnblogs.com/jevious/
    
    class A:
        def test(self):
            print('from A')
    
    
    class B(A):
        # def test(self):
        #     print('from B')
        pass
    
    
    class B2:
        def test(self):
            print('from B2')
    
    
    class C(A):
        def test(self):
            print('from C')
    
    
    class C2:
        def test(self):
            print('from C2')
    
    
    class D(B, B2):
        # def test(self):
        #     print('from D')
        pass
    
    
    class E(C, C2):
        def test(self):
            print('from E')
    
    
    class F(D, E):
        # def test(self):
        #     print('from F')
        pass
    
    
    f1 = F()
    f1.test()

    輸出結果自己列印┗|`O′|┛ 嗷~~

    那這個繼承關係是什麼呢????

    ~~核心程式設計(五):物件導向——多繼承~~

    來,我的好兄弟

    告訴我,tell me

    這是什麼順序???

    廣度???

    深度???

    其實都不是,這是一個叫C3演算法來計算繼承順序的

    不打算說,因為我也不會

    所以你要是想研究

    你就去難為百度去,行不?

    那我就想知道繼承順序怎麼辦??

    好說,程式設計師都給你寫出來方法了

    print(F.__mro__)  # 列印類的繼承順序

    你列印出來的就是繼承順序!

    (<class '__main__.F'>, 
     <class '__main__.D'>, 
     <class '__main__.B'>,
     <class '__main__.E'>, 
     <class '__main__.C'>, 
     <class '__main__.A'>, 
     <class '__main__.B2'>, 
     <class '__main__.C2'>, 
     <class 'object'>)

    都有方法了,你還自己找???

    那你可真是個小機靈!

    其實這都是很極端的

    真正寫的哪有這麼繼承的?

    頂多就寫到shijie那種就可以了

    寫成這樣的

    不是天才,就是瘋子!


*三大特性之一*
*你不會能行嗎*

相關文章