協議:不允許實例化的類以及必須被重寫的方法

說了方法的重寫,我們再回過頭來看看那個繼承樹:

類的繼承樹
類的繼承樹

這個看起來應該還行,我們可以創建大刀的實例,創建手槍的實例……

但是如果我要這樣寫呢?

那麼問題來了:挖掘機……

不,我們的問題是“武器”到底是個什麼東西?

我們說“動物”,人是動物,鳥是動物,狗、貓都是動物,那有沒有個動物是動物呢?

答案是沒有——動物是個抽象的詞彙。同樣的,作為繼承樹頂端的類,它也必定是個極為抽象的傢伙,從這裡實例化出來的——不,絕不應該讓它實例化!

所以,我們一定能找到一種辦法來讓類只能被繼承,不能被初始化。

抽像類

針對我們的這個繼承樹來說,“武器”、“冷兵器”、“熱兵器”、“槍械”、“遠程”等這些類都不應該被實例化,它們都是抽象的東西,所以我們要把這些類作為抽像類來對待,讓它必須被繼承了才能使用,而且裡邊的方法必須被重寫了才能調用!

也就是說只規定合同框架,要由子類自己去實現合同細則。

第一種方法

通過將初始化器搞成私有,這樣我們在調用一個類來實例它的時候,編譯器卻找不到初始化器——目前我們還沒有講到初始化器,而且也沒有寫出來,現在你只需要知道,我們不寫的話編譯器會自己幫你實現一個基本的,如果寫了,編譯器就會用你的。

總之,我們用這樣的方法實現了這個類無法被初始化。

 

要測試這種方法,不能在 playground 裡,必須新建個項目使用不同的文件來操作才行!

第二種方法

換一種思路,把類替換為協議來聲明——因為協議天生就是不能被實例化的……

協議

聲明協議和聲明類差不多的,都是大寫開頭的命名方法,不過 class 要換成 protocol 。

在協議裡不能設定屬性的值也不能實現方法,只能像佔位符一樣寫出規範,而子類來進行繼承的時候就會被要求覆蓋和實現這些成員。

我們來舉個栗子

這樣雖然說變成了一個協議,但它確實可以讓這個類無法被實例化,當然了,繼承自這個協議的子類則不需要重寫方法——因為方法本身就沒有被實現,我們只需要自己實現一個即可。

這裡我們的說法不太嚴謹,對於協議來講是不能被繼承的,而且也不是子類和父類的關係——目前你可以這樣理解和使用,因為對於 Swift 本身來說,並沒有抽像類的概念。

有不能被覆蓋和繼承的解決辦法嗎?

使用 final 前綴標記一個類或者方法,用來聲明這個類或者方法是“最終”的版本,不能夠被繼承或者重寫。

由...出版 R0uter

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

發表評論

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