再看繼承
真正的大餐來之前,還是來點兒開胃菜!回顧一下關于類的繼承的知識:
我們先看上面的代碼,這是一個簡單的類繼承,我們可以看到父類Base和子類Son,它們中各有一個Testfunc方法,當我們實例化子類的對象sonobj時,可以看到初始化方法中黃色框框調用了Testfunc,那么這個時候執行的是哪個類里面的代碼呢?我會告訴你執行的是子類里面的方法,不信就自己試試吧,代碼在下面~
為什么呢?其實這里是繞了一個圈,所以把很多人繞暈了,包括我!后來想想其實很容易,我們看最右邊的圖:
如果這樣看,我們是不是就明白了?其實這兩段代碼表示的是一個意思,盡管Son繼承了Base類,父子類中都有同樣的方法,但是由于我們實例化了子類的對象,所以這個在初始化方法里的self.Testfunc,self指的是子類的對象,當然也就先調用子類中的方法啦。
所以盡管在第一個例子中,初始化方法在父類執行,但是還是改變不了它是子類對象的本質,當我們使用self去調用Testfunc方法時,始終是先調用子類的方法。我們可以這樣理解,盡管兒子繼承了父親的財產,但是花錢的時候,還是要先花自己的~~~
#_*_coding:utf-8_*_ __author__ = 'Eva_J' class Base(object): def __init__(self,name): self.name = name self.Testfunc() def Testfunc(self): print 'do Base Testfunc' class Son(Base): def Testfunc(self): print 'do Son Testfunc' sonobj = Son('sonobj') inherit Code
看完剛剛的代碼,我們就知道了對象和self的真實意義,現在再來回憶一下關于繼承的順序問題:
看上面的代碼,我們猜測一下,執行之后,控制臺會打印什么呢?先揭曉答案,會打印Base2方法中的內容,原因很簡單:盡管這三個類中都有同樣的Testfunc方法,但是,由于計算機在找方法的時候,遵循的順序是:Base2,Son,Base,所以它會先找到Base2類,而這個類中剛好有它要找的方法,它也就歡歡喜喜的拿去執行啦!
#_*_coding:utf-8_*_ __author__ = 'Eva_J' class Base(object): def Testfunc(self): print 'do Base Testfunc' class Son(Base): def __init__(self,name): self.name = name self.Testfunc() def Testfunc(self): print 'do Son Testfunc' class Base2(object): def Testfunc(self): print 'do Base2 Testfunc' class GrandSon(Base2,Son): pass #sonobj = Son('sonobj') sonobj = GrandSon('sonobj') inherit2 Code
畫個簡易類圖
剛剛我們只是寫了一個小程序,來說明類之間的繼承和對象調用方法之間的聯系,但是如果我們想要hold住一個繼承關系復雜的源碼邏輯,就需要類圖來幫忙!如果你覺得我要教你畫類圖那就大錯特錯了。。。懶人癥重癥患者是懶得畫那種東西的。。。嘻,先看圖!
對照類圖看源碼
根據上面的圖,我們就拿到了threadingTCPServer的相關類,并且搞清楚了它們之間的繼承關系和方法,接下來我們對照這張簡易類圖來看看代碼執行的過程:
初始化相關過程:
執行serve_forever的相關代碼:
就是這樣,我們一路按照調用軌跡去尋找,每次看到一個調用都先對照上面的簡易類圖,看看有沒有重名方法,如果有,就要找到最近的方法并查看里面的內容,以此類推:按照這種方法,就會感覺所有代碼都在一個文件一樣,媽媽再也不用擔心我看不懂源碼,哈!!!當然啦,這種方法比較山寨,自己心里知道就好,不要告訴別人你其實是這樣看懂源碼的~~~
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
