在swift 3中新增加了兩種訪問(wèn)控制權(quán)限 filePRivate
和 open
。下面將對(duì)這兩種新增訪問(wèn)控制做詳細(xì)介紹。
在原有的swift中的 private
其實(shí)并不是真正的私有,如果一個(gè)變量定義為private,在同一個(gè)文件中的其他類(lèi)依然是可以訪問(wèn)到的。這個(gè)場(chǎng)景在使用extension的時(shí)候很明顯。
這樣帶來(lái)了兩個(gè)問(wèn)題:
當(dāng)我們標(biāo)記為private時(shí),意為真的私有還是文件內(nèi)可共享呢?當(dāng)我們?nèi)绻鈭D為真正的私有時(shí),必須保證這個(gè)類(lèi)或者結(jié)構(gòu)體在一個(gè)單獨(dú)的文件里。否則可能同文件里其他的代碼訪問(wèn)到。由此,在swift 3中,新增加了一個(gè) fileprivate
來(lái)顯式的表明,這個(gè)元素的訪問(wèn)權(quán)限為文件內(nèi)私有。過(guò)去的private對(duì)應(yīng)現(xiàn)在的fileprivate。現(xiàn)在的private則是真正的私有,離開(kāi)了這個(gè)類(lèi)或者結(jié)構(gòu)體的作用域外面就無(wú)法訪問(wèn)。
open則是彌補(bǔ)public語(yǔ)義上的不足。現(xiàn)在的pubic有兩層含義:
這個(gè)元素可以在其他作用域被訪問(wèn)這個(gè)元素可以在其他作用域被繼承或者override繼承是一件危險(xiǎn)的事情。尤其對(duì)于一個(gè)framework或者module的設(shè)計(jì)者而言。在自身的module內(nèi),類(lèi)或者屬性對(duì)于作者而言是清晰的,能否被繼承或者override都是可控的。但是對(duì)于使用它的人,作者有時(shí)會(huì)希望傳達(dá)出這個(gè)類(lèi)或者屬性不應(yīng)該被繼承或者修改。這個(gè)對(duì)應(yīng)的就是 final
。
final
的問(wèn)題在于在標(biāo)記之后,在任何地方都不能override。而對(duì)于lib的設(shè)計(jì)者而言,希望得到的是在module內(nèi)可以被override,在被import到其他地方后其他用戶使用的時(shí)候不能被override。
這就是 open
產(chǎn)生的初衷。通過(guò)open和public標(biāo)記區(qū)別一個(gè)元素在其他module中是只能被訪問(wèn)還是可以被override。
下面是例子:
/// ModuleA:// 這個(gè)類(lèi)在ModuleA的范圍外是不能被繼承的,只能被訪問(wèn)public class NonSubclassableParentClass { public func foo() {} // 這是錯(cuò)誤的寫(xiě)法,因?yàn)閏lass已經(jīng)不能被繼承, // 所以他的方法的訪問(wèn)權(quán)限不能大于類(lèi)的訪問(wèn)權(quán)限 open func bar() {} // final的含義保持不變 public final func baz() {}}// 在ModuleA的范圍外可以被繼承open class SubclassableParentClass { // 這個(gè)屬性在ModuleA的范圍外不能被override public var size : Int // 這個(gè)方法在ModuleA的范圍外不能被override public func foo() {} // 這個(gè)方法在任何地方都可以被override open func bar() {} ///final的含義保持不變 public final func baz() {}}/// final的含義保持不變public final class FinalClass { }/// ModuleB:import ModuleA// 這個(gè)寫(xiě)法是錯(cuò)誤的,編譯會(huì)失敗// 因?yàn)镹onSubclassableParentClass類(lèi)訪問(wèn)權(quán)限標(biāo)記的是public,只能被訪問(wèn)不能被繼承class SubclassA : NonSubclassableParentClass { }// 這樣寫(xiě)法可以通過(guò),因?yàn)镾ubclassableParentClass訪問(wèn)權(quán)限為 `open`.class SubclassB : SubclassableParentClass { // 這樣寫(xiě)也會(huì)編譯失敗 // 因?yàn)檫@個(gè)方法在SubclassableParentClass 中的權(quán)限為public,不是`open'. override func foo() { } // 這個(gè)方法因?yàn)樵赟ubclassableParentClass中標(biāo)記為open,所以可以這樣寫(xiě) // 這里不需要再聲明為open,因?yàn)檫@個(gè)類(lèi)是internal的 override func bar() { }}open class SubclassC : SubclassableParentClass { // 這種寫(xiě)法會(huì)編譯失敗,因?yàn)檫@個(gè)類(lèi)已經(jīng)標(biāo)記為open // 這個(gè)方法override是一個(gè)open的方法,則也需要表明訪問(wèn)權(quán)限 override func bar() { } }open class SubclassD : SubclassableParentClass { // 正確的寫(xiě)法,方法也需要標(biāo)記為open open override func bar() { } }open class SubclassE : SubclassableParentClass { // 也可以顯式的指出這個(gè)方法不能在被override public final override func bar() { } }現(xiàn)在的訪問(wèn)權(quán)限則依次為:open,public,internal,fileprivate,private。有的人會(huì)覺(jué)得訪問(wèn)權(quán)限選擇的增加加大了語(yǔ)言的復(fù)雜度。但是如果我們思考swift語(yǔ)言的設(shè)計(jì)目標(biāo)之一就是一門(mén)安全的語(yǔ)言(“Designed for Safety”)就能理解這次的改動(dòng)。更加明確清晰的訪問(wèn)權(quán)限控制可以使程序員表達(dá)出更準(zhǔn)確的意圖,當(dāng)然也迫使在編碼時(shí)思考的更加深入。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注