final
關(guān)鍵字可以用在蔫敲,或者前面進(jìn)行修飾添履,表示不允許對該內(nèi)容進(jìn)行繼承或者重寫操作憎乙。這個關(guān)鍵字的作用和C#中的相同票罐,而其實在C#算是一個飽受爭議的關(guān)鍵字。有一派程序員認(rèn)為泞边,類似這樣的禁止繼承和重寫的做法是非常有益的该押,它可以更好地對代碼進(jìn)行版本控制,得到更佳的性能阵谚,以及使代碼更安全蚕礼。因此他們甚至認(rèn)為語言應(yīng)當(dāng)是默認(rèn)不允許繼承的,只有在顯式地指明可以繼承的時候才能子類化梢什。
在寫Swift的時候可能會在什么情況下使用
權(quán)限控制
給一段代碼加上就意味著編譯器向你作出保證奠蹬,這段代碼不會再被修改;同時,這也意味著你認(rèn)為這段代碼已經(jīng)完備并且沒有再被進(jìn)行繼承或重寫的必要嗡午,因此這往往會是一個需要深思熟慮的決定囤躁。在Cocoa開發(fā)中app開發(fā)是一塊很大的內(nèi)容,對于大多數(shù)我們自己完成的面向app開發(fā)代碼,其實不太會提供給別人使用割以,這種情況下即使是將所有自己寫的代碼標(biāo)記為都是一件無可厚非的事情(但我并不是在鼓勵這么做) --因為在需要的任何時候你都可以將這個關(guān)鍵字去掉以恢復(fù)其可繼承性金度。而在開發(fā)給其他開發(fā)者使用的庫時,就必須更深入地考慮各種使用場景和需求了严沥。
一般來說猜极,不希望被繼承和重寫會有這幾種情況:
類或者方法的功能確實已經(jīng)完備了
對于很多的輔助性質(zhì)的工具類或者方法,可能我們會考慮加上消玄。這樣的類有一個比較大的特點跟伏,是很可能只包含類方法而沒有實例方法。比如我們很難想到一種情況需要繼承或重寫一個負(fù)責(zé)計算一段字符串的MD5或者AES加密解密的工具類翩瓜。這種工具類和方法的算法是經(jīng)過完備驗證和固定的受扳,使用者只需要調(diào)用,而相對來說不可能有繼承和重寫的需求兔跌。
這種情況很多時候遵循的是以往經(jīng)驗和主觀判斷勘高,而單個的開發(fā)者的判斷其實往往并不可靠。遇到希望把某個自己開發(fā)的類或者方法標(biāo)為的時候坟桅,去找?guī)讉€富有經(jīng)驗的開發(fā)者华望,問問他們的意見或者看法,應(yīng)該是一個比較靠譜的做法仅乓。
子類繼承和修改是一件危險的事情
在子類繼承或重寫某些方法后可能做一些破壞性的事情赖舟,導(dǎo)致子類或者父類部分也無法正常工作的情況。舉個例子夸楣,在某個公司管理的系統(tǒng)中我們對員工按照一定規(guī)則進(jìn)行編號宾抓,這樣通過編號我們能迅速找到任一員工。而假如我們在子類中重寫了這個編號方法豫喧,很可能就導(dǎo)致基類中的依賴員工編號的方法失效石洗。在這類情況下,將編號方法標(biāo)記為以確保穩(wěn)定紧显,可能是一種更好的做法劲腿。
為了父類中某些代碼一定會被執(zhí)行
有時候父類中有一些關(guān)鍵代碼是在被繼承重寫后必須執(zhí)行的(比如狀態(tài)配置,認(rèn)證等等)鸟妙,否則將導(dǎo)致運行時候的錯誤。而在一般的方法中挥吵,如果子類重寫了父類方法重父,是沒有辦法強(qiáng)制子類方法一定去調(diào)用相同的父類方法的。在Objective-C的時候我們可以通過指定__attribute__((objc_requires_super))這樣的屬性來讓編譯器在子類沒有調(diào)用父類方法時拋出警告忽匈。
在Swift中對原來的很多attribute的支持現(xiàn)在還缺失中房午,為了達(dá)到類似的目的,我們可以使用一個final的方法丹允,在其中進(jìn)行一些必要的配置郭厌,然后再調(diào)用某個需要子類實現(xiàn)的方法袋倔,以確保正常運行:
class ? ?Parent{
? ? ? final fun method() {?
? ? ? ? ? ? ? ? methodImpl()
? ? ? ?}
func methodImpl(){ fatalError("子類必須實現(xiàn)這個方法")}
}
class ?Child: Parent {
override ? func ?methodImpl(){ //..子類的業(yè)務(wù)邏輯}
}
這樣,無論如何我們?nèi)绾问褂谜勰伎梢员WC需要的代碼一定被運行過宾娜,而同時又給了子類繼承和重寫自定義具體實現(xiàn)的機(jī)會。
性能考慮
使用final的另一個重要理由是可能帶來的性能改善扇售。因為編譯器能夠從final中獲取額外的信息前塔,因此可以對類或者方法調(diào)用進(jìn)行額外的優(yōu)化處理。但是這個優(yōu)勢在實際表現(xiàn)中可能帶來的好處其實就算與Objective-C的動態(tài)派發(fā)相比也十分有限邪驮,因此在項目還有其他方面可以優(yōu)化(一般來說會是算法或者圖形相關(guān)的內(nèi)容導(dǎo)致性能瓶頸)的情況下溃列,并不建議使用將類或者方法轉(zhuǎn)為的方式來追求性能的提升暗挑。