Python 類的繼承

來源:互聯網
上載者:User

標籤:類   python   

    繼承(Inheritance)是物件導向軟 件技術當中的一個概念。如果一個類別 A“繼承自”另一個類別 B,就把這個 A 稱為“B 的子類別”,而把 B 稱為“A 的父系類別”,也可以稱“B 是 A 的超類”。

    繼承可以使得子類別具有父系類別的各種屬性和方法,而不需要再次編寫相同的代碼。在令子類別繼承父系類別的同時,可以重新定義某些屬性,並重寫某些方法,即覆蓋父系類別的原有屬性和方法,使其獲得與父系類別不同的功能。另外,為子類別追加新的屬性和方法也是常見的做法。 (源自維基百科)


    由上面對繼承的表述,可以簡單總結出繼承的意圖或者好處:

    1、可以實現代碼重用,但不是僅僅實現代碼重用,有時候根本就沒有重用

    2、實現屬性和方法繼承


#!/usr/bin/env Python# coding=utf-8__metaclass__ = typeclass Person:    def speak(self):        print "I love you."    def setHeight(self, n):        self.length = n    def breast(self, n):        print "My breast is: ",nclass Girl(Person):    def setHeight(self):        print "The height is:1.70m ."if __name__ == "__main__":    cang = Girl()    cang.setHeight()    cang.speak()    cang.breast(90)

儲存,執行

$ python 20901.py The height is:1.70m .I love you.My breast is:  90

    對以上程式進行解釋,從中體會繼承的概念和方法。

    首先定義了一個類 Person,在這個類中定義了三個方法。注意,沒有定義初始化函數,初始化函數在類中不是必不可少的。

    然後又定義了一個類 Girl,這個類的名字後面的括弧中,是上一個類的名字,這就意味著 Girl 繼承了 Person,Girl 是 Person 的子類,Person 是 Girl 的父類。

    既然是繼承了 Person,那麼 Girl 就全部擁有了 Person 中的方法和屬性(上面的例子雖然沒有列出屬性)。但是,如果 Girl 裡面有一個和 Person 同樣名稱的方法,那麼就把 Person 中的同一個方法遮蓋住了,顯示的是 Girl 中的方法,這叫做方法的重寫。

    執行個體化類 Girl 之後,執行執行個體方法 cang.setHeight(),由於在類 Girl 中重寫了 setHeight 方法,那麼 Person 中的那個方法就不顯作用了,在這個執行個體方法中執行的是類 Girl 中的方法。

    雖然在類 Girl 中沒有看到 speak 方法,但是因為它繼承了 Person,所以 cang.speak() 就執行類 Person 中的方法。同理 cang.breast(90),它們就好像是在類 Girl 裡面已經寫了這兩個方法一樣。既然繼承了,就是我的了。



多重繼承

所謂多重繼承,就是只某一個類的父類,不止一個,而是多個。比如:

#!/usr/bin/env Python# coding=utf-8__metaclass__ = typeclass Person:    def eye(self):        print "two eyes"    def breast(self, n):        print "The breast is: ",nclass Girl:    age = 28    def color(self):        print "The girl is white"class HotGirl(Person, Girl):    passif __name__ == "__main__":    kong = HotGirl()    kong.eye()    kong.breast(90)    kong.color()    print kong.age

在這個程式中,前面有兩個類:Person 和 Girl,然後第三個類 HotGirl 繼承了這兩個類,注意觀察繼承方法,就是在類的名字後面的括弧中把所繼承的兩個類的名字寫上。但是第三個類中什麼方法也沒有。


然後執行個體化類 HotGirl,既然繼承了上面的兩個類,那麼那兩個類的方法就都能夠拿過來使用。儲存程式,運行一下看看

$ python 20902.py two eyesThe breast is:  90The girl is white28

值得注意的是,這次在類 Girl 中,有一個 age = 28,在對 HotGirl 執行個體化之後,因為繼承的原因,這個類屬性也被繼承到 HotGirl 中,因此通過執行個體屬性 kong.age 一樣能夠得到該資料。


由上述兩個執行個體,已經清楚看到了繼承的特點,即將父類的方法和屬性全部承接到子類中;如果子類重寫了父類的方法,就使用子類的該方法,父類的被遮蓋。


多重繼承的順序

多重繼承的順序很必要瞭解。比如,如果一個子類繼承了兩個父類,並且兩個父類有同樣的方法或者屬性,那麼在執行個體化子類後,調用那個方法或屬性,是屬於哪個父類的呢?造一個沒有實際意義,純粹為瞭解決這個問題的程式:

#!/usr/bin/env Python# coding=utf-8class K1(object):    def foo(self):        print "K1-foo"class K2(object):    def foo(self):        print "K2-foo"    def bar(self):        print "K2-bar"class K3(object):    passclass K4(object):    def foo(self):        print "K4-foo"class J1(K1, K2):    passclass J2(K3, K4):    def bar(self):        print "J2-bar"class C(J1, J2):    passif __name__ == "__main__":    print C.__mro__    m = C()    m.foo()    m.bar()

這段代碼,儲存後運行:

[[email protected] codes]# python cl.py(<class ‘__main__.C‘>, <class ‘__main__.J1‘>, <class ‘__main__.K1‘>, <class ‘__main__.K2‘>, <class ‘__main__.J2‘>, <class ‘__main__.K3‘>, <class ‘__main__.K4‘>, <type ‘object‘>)K1-fooK2-bar

代碼中的 print C.__mro__是要列印出類的繼承順序。順序根據C括弧裡面的父類從左至右繼承,先是J1,J1的父類K1,K2。然後到J2,最後J2的父類K3,K4。從上面清晰看出來了。如果要執行 foo() 方法,首先看 J1,沒有,看 J2,還沒有,看 J1 裡面的 K1,有了,即 C==>J1==>J2==>K1;bar() 也是按照這個順序,在 J2 中就找到了一個。


這種對繼承屬性和方法搜尋的順序稱之為“廣度優先”。



super 函數

對於初始化函數的繼承,跟一般方法的繼承,還有點不同。可以看下面的例子:

#!/usr/bin/env Python# coding=utf-8__metaclass__ = typeclass Person:    def __init__(self):        self.height = 160    def about(self, name):        print "{} is about {}".format(name, self.height)class Girl(Person):    def __init__(self):        self.breast = 90    def about(self, name):        print "{} is a hot girl, she is about {}, and her breast is {}".format(name, self.height, self.breast)if __name__ == "__main__":    cang = Girl()    cang.about("wangguniang")

在上面這段程式中,類 Girl 繼承了類 Person。在類 Girl 中,初始化設定了 self.breast = 90,由於繼承了 Person,按照前面的經驗,Person 的初始化函數中的 self.height = 160 也應該被 Girl 所繼承過來。然後在重寫的 about 方法中,就是用 self.height。


執行個體化類 Girl,並執行 cang.about("wangguniang"),試圖列印出一句話 wangguniang is a hot girl, she is about 160, and her bereast is 90。儲存程式,運行之:

$ python 20903.py Traceback (most recent call last):  File "20903.py", line 22, in <module>    cang.about("wangguniang")  File "20903.py", line 18, in about    print "{} is a hot girl, she is about {}, and her breast is {}".format(name, self.height, self.breast)AttributeError: ‘Girl‘ object has no attribute ‘height‘

報錯!


程式員有一句名言:不求最好,但求報錯。報錯不是壞事,是我們長經驗的時候,是在告訴我們,那麼做不對。


重要的是看報錯資訊。就是我們要列印的那句話出問題了,報錯資訊顯示 self.height 是不存在的。也就是說類 Girl 沒有從 Person 中繼承過來這個屬性。


原因是什嗎?仔細觀察類 Girl,會發現,除了剛才強調的 about 方法重寫了,__init__方法,也被重寫了。不要認為它的名字模樣奇怪,就不把它看做類中的方法(函數),它跟類 Person 中的__init__重名了,也同樣是重寫了那個初始化函數。


這就提出了一個問題。因為在子類中重寫了某個方法之後,父類中同樣的方法被遮蓋了。那麼如何再把父類的該方法調出來使用呢?縱然被遮蓋了,應該還是存在的,不要浪費了呀。


Python 中有這樣一種方法,這種方式是被提倡的方法:super 函數。

#!/usr/bin/env python# coding=utf-8__metaclass__ = typeclass Person:    def __init__(self):        self.height = 160    def about(self, name):        print "{} is about {}".format(name, self.height)class Girl(Person):    def __init__(self):        super(Girl, self).__init__()        self.breast = 90    def about(self, name):        print "{} is a hot girl, she is about {}, and her breast is {}".format(name, self.height, self.breast)        super(Girl, self).about(name)if __name__ == "__main__":    cang = Girl()    cang.about("wangguniang")

在子類中,__init__方法重寫了,為了調用父類同方法,使用 super(Girl, self).__init__()的方式。super 函數的參數,第一個是當前子類的類名字,第二個是 self,然後是點號,點號後面是所要調用的父類的方法。同樣在子類重寫的 about 方法中,也可以調用父類的 about 方法。


執行結果:

$ python 20903.py wangguniang is a hot girl, she is about 160, and her breast is 90wangguniang is about 160


Python 類的繼承

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.