再次回顧:繼承

我們這次一起來回顧一下之前幾節課裡提到的繼承,我們曾在初見OPEN 裡用了一個開發手機(系統)的栗子來描述繼承這個東西,相信大家還有印象。

繼承

那麼這節課我們就深入的來了解了解繼承這個概念。

這個其實也不難理解,你看,當你的父輩去世,那他們的財富就會由你繼承——好吧,這不是一件很值得開心的事情,但這畢竟是事實。

還有,比如說某一家子人父親退休了,他的公司就由兒子掌管,我們說這是“子承父業”。

最後說回到 Swift 裡邊,就是子類繼承了父類的成員。這裡我們講“成員”,就是指類裡邊的屬性和方法。

舉個栗子吧:這還是一個手機的類

我們寫子類來繼承父類:

對於父類 CellPhone 來說,它比較抽象,怎麼個抽像法呢?任何一部能稱得上手機的設備,肯定都具有這樣的功能——撥號,打電話,發短信。

對於子類我們確實生產的手機,它就只有最基本的功能,所以 phone 類只需要繼承自 CellPhone 就好了,它雖然沒有寫任何的屬性和方法,但它天生就有了 CellPhone 裡的全部屬性和方法。

對於我們的智能手機 smartPhone ,我們增加了發郵件和上網的功能,但沒有實現手機的基本功能——可是它繼承自 CellPhone,所以它天生就也帶有了手機的所有功能。

至於電量和號碼這兩個屬性,兩個子類則可以設定它們各自的內容。

設計一個繼承樹

假設說我們要開發遊戲,這個遊戲既有武俠也有科技,既有英雄也有美人——所以說肯定是有戰爭的——有美人嘛。有了戰爭,就要有兵器,那麼我們就創建一個關於武器的繼承樹。

首先,設計師告訴我們,一共要有以下幾種武器:機槍、手槍、步槍、長劍、開山刀、木棍、內力(這個也算?)、鐵鎚、弩箭、弓箭、暗器……好了,夠多了。

第一步,找出具有共同屬性和行為的對象

問一問自己:這些武器都有什麼共同點?

啊……這太麻煩了,為什麼不干脆每一個武器來一個類呢?

——也不是不行,但是這樣的話肯定就會有好多重複的代碼了,這樣會讓整個代碼行數大大增加,一個是不利於維護,一旦我們要修改這些武器的某些屬性呢?挨個改吧!另一個,就是你程序的 bug 數量是和代碼行數成正比的……所以我們有必要有責任也有義務保證代碼的簡潔。

好了,這些武器肯定得有個屬性來保存它們的模型,還得有耐久度吧?得有攻擊力,有攻擊範圍,還得有攻擊類型,有等級要求……暫時這麼多吧

它們的行為,比如說有攻擊,防禦,警戒……這樣,我們就有了三個方法:

這樣,我們就能從武器這裡繼承出各種各樣的武器了!來我們算一算,假設設計師要100中特定的武器,難道真的要把上邊這樣的代碼重複寫一百遍嗎? ! (小學生都不屑如此啦)

好了,現在我們再來看看,冷兵器和熱兵器是不同的,它們的攻擊方法完全不一樣,刀和劍都可以揮砍,但弩和弓就要射擊,我們讓子類自行覆蓋父類的方法——覆蓋後邊再說,簡單的用法你是知道的。

但是還有個問題,手槍機槍都要有子彈有彈夾,這些似乎還是可以提取出來——沒錯,在眾多子類裡邊,尋找更多可以抽象化的方法是個不錯的選擇,我們來設計另外一個武器的子類但又是槍支的父類:

這樣,我們用槍械這個類去繼承出一個子類的話,那它就有了彈藥和彈夾,還有屬於槍械的攻擊防禦方法。

完成類的繼承樹

按照上邊的設計思路,我們現在來完成這個繼承樹:

類的繼承樹
類的繼承樹

等等,到底調用哪個方法?

現在我們有了繼承樹,也按照繼承樹繼承出了最終的實例……可是這個時候怎麼確定調用的方法在哪裡呢?

首先,既然我們有了繼承樹,那麼編譯器肯定也能夠知道,那就是說肯定會找到你要調用的方法。

其次,一般我們按照一個遞歸的方式來查詢,從這個繼承樹最底下開始(也就是最具體的對像開始),一層一層往上查找,知道找到一個對應的——也就是說最接近對象的那個方法就是我們要調用的方法。

比如我們創建了一個手槍的實例,手槍裡並沒有攻擊的方法,我們調用攻擊,編譯器就會網上查找,找到了父類裡重寫了的攻擊方法——而不是找到最頂層的最原始的攻擊方法。

由...出版 R0uter

如非聲明,本人所著文章均為原創手打,轉載請註明本頁面鏈接和我的名字。

加入對話

1 評論

您的電子郵件地址不會被公開. 必填字段標 *