python3面向對象(2)之super()


super()是一個什么鬼?干什么用的?打開菜鳥教程看一下super()的簡介;第一句話就是:super()函數是用來調用父類(超類)的一個方法。嗯哦;原來是一個函數可以返回一個父類的方法:於是我就這樣理解了,那么如果是多繼承呢,是返回所有父類的被調用的方法嗎?一個疑問?看看下面的代碼(先定義一個人類,然后定義一個男人,一個女人,一個兒子)

class Person(object):     #定義一個人類,繼承objec
    def __init__(self):
        print("我要好好學習")

    def study(self):
        print("我要學好語言")


class man(Person):   #定義一個男人,繼承人類
    def __init__(self):
        print("我是男人我要好好學習")

    def study(self):
        print("我要學好數學")
        


class woman(Person):    #定義一個女人,繼承人類
    def __init__(self):
        print("我是女人我要好好學習")

    def study(self):
        print("我要學好英語")
      

class son(man,woman):  #定義一個兒子,繼承男人和女人
    def __init__(self):
        print("我是兒子我要好好學習")

    def study(self):
        print("我要學好化學和物理")
# woman.study(self) # man.study(self) super().study() # def study1(self): # print("我要學好英語") son1 = son() son1.study() # son1.study1()
解釋:先定義一個人類,定義一個方法:我要學好語言;然后定義一個男人:我要學好數學;再定義一個女人:我要學好英語;最后定義一個兒子學好化學和物理;在定義方法的時候我們都使用了study函數;所以子類的函數
會覆蓋父類的函數;最后實例化一個son1的對象調用study函數只會輸出:我要學好化學和物理;但是這個時代光會這兩門也不行啊;還得學好英語啊,那么怎么辦呢? ok 簡單

在這個son的類中增加一個study1函數不就完了嘛,嗯,對確實完了;但是這樣卻增加了不必要的代碼啊,學習英語這件事woman類中不是有了嗎?我們不能直接使用這里的嗎?當然可以,於是有了第二種方法:

在son的類中的study函數中增加了 woman.study(self) 這句好相當於直接調用woman類中的study函數 同理也可以直接調用man類中的study函數;這樣就不用創建新函數了;這種等於直接調用。我們還可以使用另外
一種方式來調用man和woman中的study函數即:super().study();前面兩種我們已經注釋掉了我們只研究最后一種;即出現了上面的代碼;那么這段代碼會
出現什么呢?(反正我一開始覺得super()不是調用父類的方法嘛,既然son有兩個父類,兩個父類的study函數一起調用了唄,可是結果呢)

 

 代碼執行結果:

我是兒子我要好好學習
我要學好化學和物理
我要學好數學

 噫噫噫,不對啊,和我想的不一樣啊,只返回了man類中的方法;沒有返回woman類中的方法啊;這是什么情況呢?一百的問號????

於是查看了很多的博客,畢竟還是有很多大神的嘛我們要向前輩們學習啊,於是對super()又有了新的認識:我們返回文章的第一句話,super()是個什么鬼?從新解釋一下:super()不是一個函數而是一個類,super()相當於這個類調用了自己的初始化函數,返回了一個對象;這個對象是干嘛的呢,用來調用實例化對象中的mro()序列中的下一個  的  類的指定的類中的方法(mro()返回的是一個:方法解析順序列表)估計又懵了,那么我們先打印一下:son.mro()

[<class '__main__.son'>, <class '__main__.man'>, <class '__main__.woman'>, <class '__main__.Person'>, <class 'object'>]

實際上打印出來的就是son的繼承父類的順序(son---man---woman---Person---object)

那么以本例來說在son中寫了super(),那么son的下一個mro當然就是man類,所以就返回了man類中的study方法了。這就是上面那個疑問的解答了;那么問題又來了如果我在man類中也寫了super().study(),那么接下來會打印什么呢?無非就兩個可能一個是打印Person中的sutdy方法另一個可能就是打印woman類中的study方法(為什么是這兩種呢,如果我們是以son為出發點man的下一個mro當然是woman;但是我們現在是把super().study()寫在了man類中這個時候好像以man類為出發點也說的過去啊,那么我們先打印一下man,mro()。)

class man(Person):
    def __init__(self):
        print("我是男人我要好好學習")

    def study(self):
        print("我要學好數學")
        super().study()

結果:
[<class '__main__.man'>, <class '__main__.Person'>, <class 'object'>]

 果然man的下一個mro是Person而不是woman啊,如果我們執行上面的代碼最終到底是打印person呢還是woman呢?看結果:

我是兒子我要好好學習
[<class '__main__.son'>, <class '__main__.man'>, <class '__main__.woman'>, <class '__main__.Person'>, <class 'object'>]
[<class '__main__.man'>, <class '__main__.Person'>, <class 'object'>]
我要學好化學和物理
我要學好數學
我要學好英語

 打印出來的是我要學好英語是woman中的(而不是person中的);如果我們在woman類中也一起寫上super(),那么:

class Person(object):
    def __init__(self):
        print("我要好好學習")

    def study(self):
        print("我要學好語言")


class man(Person):
    def __init__(self):
        print("我是男人我要好好學習")

    def study(self):
        print("我要學好數學")
        super().study()


class woman(Person):
    def __init__(self):
        print("我是女人我要好好學習")

    def study(self):
        print("我要學好英語")
        super().study()

class son(man,woman):
    def __init__(self):
        print("我是兒子我要好好學習")

    def study(self):
        print("我要學好化學和物理")
        # woman.study(self)
        # man.study(self)

        super().study()

    # def study1(self):
    #     print("我要學好英語")


son1 = son()
print(son.mro())
print(man.mro())
son1.study()
# son1.study1()

 結果:

我是兒子我要好好學習
[<class '__main__.son'>, <class '__main__.man'>, <class '__main__.woman'>, <class '__main__.Person'>, <class 'object'>]
[<class '__main__.man'>, <class '__main__.Person'>, <class 'object'>]
我要學好化學和物理
我要學好數學
我要學好英語
我要學好語言

 看一下結果就知道了先打印了man類中的study方法,之后打印了woman類中的方法;最后打印了Person類中的study方法;所以到這里暫時得到一個結論:super()不是指父類(對於man類來說Person應該是父類)而只指以實例化對象為起點的mro序列中的下一個。

那么我們把上面的代碼再來改一改,如果我把man類中的super()注釋掉了,但是woman類中保留着super()會又什么樣的的結果呢:

class Person(object):
    def __init__(self):
        print("我要好好學習")

    def study(self):
        print("我要學好語言")


class man(Person):
    def __init__(self):
        print("我是男人我要好好學習")

    def study(self):
        print("我要學好數學")
        # super().study()

class woman(Person):
    def __init__(self):
        print("我是女人我要好好學習")

    def study(self):
        print("我要學好英語")
        super().study()

class son(man,woman):
    def __init__(self):
        print("我是兒子我要好好學習")

    def study(self):
        print("我要學好化學和物理")
        # woman.study(self)
        # man.study(self)

        super().study()

    # def study1(self):
    #     print("我要學好英語")


son1 = son()

print(son.mro())
print(man.mro())

son1.study()


# son1.study1()

 結果:

我是兒子我要好好學習
[<class '__main__.son'>, <class '__main__.man'>, <class '__main__.woman'>, <class '__main__.Person'>, <class 'object'>]
[<class '__main__.man'>, <class '__main__.Person'>, <class 'object'>]
我要學好化學和物理
我要學好數學

 結果是man類中的sutdy方法打印出來了然而woman和Person類中的study方法沒有打印出來;相當與 son--man--woman中在man這里打斷了,然后后面的也就不執行了。

好吧就到這里吧由於剛開始學習python,對於super()理解的還有很多不到位的地方;以后這篇文章還需要改進,暫時理解到這個程度。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM