原文再續(xù),書折第一回。
很多其他編程語言都有一種”protected“設(shè)定,可以限制某些類方法只能被它的子類所使用。
Swift 支持了訪問控制后,大家給我們的反饋都很不錯。而有的開發(fā)者問我們:“為什么 Swift 沒有類似 protected 的選項?”
當(dāng)我們在設(shè)計 Swift 訪問控制的不同等級時,我們認(rèn)為有兩種主要場景:
上面的兩種常見情況,對應(yīng)著 private 和 internal 這兩個等級。
而 protected 相當(dāng)于把訪問控制和繼承特性混在一起,把訪問控制的等級設(shè)定增加了一個維度,使之復(fù)雜化。即使設(shè)定了 protected,子類還是可以通過新的公開方法、新的屬性來接觸到所謂“protected”了的 API。另一方面,我們可以在各種地方重寫一個方法,所謂的保護(hù)卻沒有提供優(yōu)化機(jī)制。這種設(shè)定往往在做不必要的限制 一 protected 允許了子類,但又禁止所有其他別的類(包括那些幫助子類實現(xiàn)某些功能的類)接觸父類的成員。
有的開發(fā)者指出,apple 的框架有時候也會把給子類用的 API 分隔出來。這時候 protected 不就有用了嗎?我們研究后發(fā)現(xiàn),這些方法一般屬于下面兩種情況:一是這些方法對子類以外的類沒啥用,所以不需要嚴(yán)格保護(hù)(例如上面說的協(xié)助實現(xiàn)某些功能的類)。二是這些方法就是設(shè)計出來被重寫,而不是直接用的。舉個例子,drawRect(_:) 就是在 UIKit 基礎(chǔ)上使用的方法,但它不能在 UIKit 以外應(yīng)用。
除此之外,如果有了 protected,它要怎么樣和 extension 相互作用呢?一個類的 extension 能接觸它的 protected 成員嗎?一個子類的 extension 可以接觸父類的 protected 成員嗎?extension 聲明的位置對訪問控制等級有沒有影響呢?(復(fù)雜到要哭了是不是?)
對訪問控制的設(shè)計,也依循了 Objective-C 開發(fā)者(包括 apple 內(nèi)外的)的常規(guī)做法。Objective-C 方法和屬性一般在.h 頭文件里聲明,但也可以寫在.m 實現(xiàn)文件里。假如有一個公開的類,想把里面某些部分設(shè)為只有框架內(nèi)可以獲取時,開發(fā)者一般會創(chuàng)建另一個頭文件給內(nèi)部使用。以上三種訪問級別,就對應(yīng)了 Swift 里面的 public,private 和 internal。
Swift 的訪問控制等級和繼承無關(guān),是單維度、非常清楚明了的。我們認(rèn)為這樣的模式更簡潔,同時滿足了最主要的需求:將一個類、或一個框架的實現(xiàn)細(xì)節(jié)隔離保護(hù)起來。這可能和你以前用過的不同,但我們鼓勵你試試看。
本章節(jié)不是老碼的原創(chuàng),是老碼認(rèn)真的閱讀了蘋果的官方博客,自己的練習(xí)總結(jié),如果小伙伴們費了吃奶的勁還是看不懂,請找度娘谷歌。還是看不懂?請到老碼官方微博咆哮。