Swift:細說實體訪問等級

代碼中各個實體之間的相互訪問是有限制的难衰,不同的實體可能有不同的訪問等級笆怠。不同的訪問等級由不同的關鍵字標識堕虹,比如很多高級語言中的 publicprivate 關鍵字虱黄,就標識了不同的訪問等級

Swift 有5種不同的訪問等級余掖,等級越高表示訪問受限性越小。訪問等級從高到低礁鲁,由關鍵字依次表示為:
open > public > internal > fileprivate > private默認的訪問等級是 internal

模塊與源文件

Swift 中實體之間的訪問是基于模塊和源文件的赁豆,所以仅醇,首先了解一下 Swift 的模塊與源文件:

  • 模塊 (Module)

  • 一個模塊是代碼分布中一個單一的單元。比如一個能被其它模塊通過 import 關鍵字導入的framework 或 程序

  • 在 Xcode 中魔种,每一個 Target 都是一個獨立的模塊

  • 源文件 (Source file)

  • 這個很好理解析二,就是你工程里新建的代碼文件

區(qū)分訪問等級
  • open , public
    openpublic 定義的實體可以被相同Module 中的源文件訪問,也可以通過 import 其它Module ,被這些Module 的源文件訪問叶摄。但 openpublic是有區(qū)別的:

  • open只作用于類和類成員

  • 除了 open属韧,被其它4個關鍵字修飾的類,只能被相同 Module 中的其它類繼承

  • 除了 open蛤吓,被其它4個關鍵字修飾的類成員宵喂,只能被相同 Module 中的子類重寫

  • open 修飾的類,既可以被相同 Module 中的類繼承会傲,又可以被通過 import 導入的Module 中的類繼承

  • open 修飾的類成員锅棕,既可以被相同 Module 中的子類重寫,又可以被通過 import 導入的Module 中的子類重寫

  • internal
    internal 定義的實體只能被相同 Module 中的源文件訪問淌山,但不能被其它Module 的源文件訪問

  • fileprivate
    fileprivate 定義的實體只能在它被定義的源文件中使用裸燎,如果你不想讓別人知道某個功能的詳細實現(xiàn),使用fileprivate 來修飾這個方法泼疑,那么它的實現(xiàn)過程將被隱藏

  • private
    private 定義的實體德绿,只在它被定義的大括號{}內有效

子類的訪問等級

子類的訪問等級不能超過他的父類。但是對于里面可以重載的 類成員(屬性退渗,方法移稳,構造器),卻有著獨特的一面

  • 被子類重載的類成員氓辣,可以擁有比在父類里更高的訪問等級秒裕,如下面的兩個類,類 B 重載了父類的 someMethod 方法钞啸,并且賦予了它新的更高的訪問等級 internal
public class A {
      private func someMethod() {}
}
internal class B:A {
      override internal func someMethod() {}
}
  • 子類成員可以調用父類成員几蜻,并且這個父類成員比這個子類成員的訪問等級低。這個父類成員需要符合兩條原則:父類和子類定義在相同的源文件中体斩,對于父類的private成員梭稚;父類和子類定義在相同的Module 中,對于父類的 internal 成員
//兩個類在相同的源文件中
public class A {
      private func someMethod() {}
}
internal class B:A {
      override internal func someMethod() {
         super.someMethod()
      }
}
Getter 與 Setter

gettersetter 默認和原屬性訪問等級相同絮吵,但是Swift 允許我們給 setter 設置比原屬性低的訪問等級弧烤,這樣可以起到有效的 讀寫保護。語法是蹬敲,在 var前寫上fileprivate(set), private(set)internal(set)set 可以換成 get

struct TrackedString {
    private(set) var numberOfEdits = 0 //記錄 value 被修改的次數(shù)
    var value: String = "" {
        didSet {
           numberOfEdits += 1          //每次 value 被修改之后暇昂,numberOfEdits 都會自動加1
        }
    }
}

上面的函數(shù)中,我們單獨設置了變量 numberOfEditssetterprivate伴嗡,而 getter 的訪問等級依然是 internal (注意:internal 可以顯式的寫在private(set) 前)急波。這樣,在外部 numberOfEdits 呈現(xiàn)出了 read-only 的屬性而不能被修改瘪校,因為它只能在被定義的大括號{} 區(qū)域內被修改澄暮。

var stringToEdit = TrackedString()
stringToEdit.value = "Value changed once"
stringToEdit.value = "Value changed twice"
stringToEdit.value = "Value changed three times"
print("The number of edits is \(stringToEdit.numberOfEdits)") // 打印出 "The number of edits is 3"
枚舉的訪問等級

如果一個枚舉的訪問等級為 public(或其它)名段,那么它的case 會自動接收相同的 public(或其它) 訪問等級。并且你不能給 case 指定訪問等級泣懊,它只能隨從它所屬的枚舉伸辟。

嵌套類型的訪問等級

嵌套類型的訪問等級,基本呈現(xiàn)出逐層降低的現(xiàn)象

  • private 類型里定義的嵌套馍刮,自動為 private
  • fileprivate類型里定義的嵌套信夫,自動為 private
  • publicinternal類型里定義的嵌套,自動為 internal渠退。另外忙迁,如果你想把一個在 public 里定義的嵌套變?yōu)楣械模敲茨阈枰@示聲明這個嵌套為 public
元組的訪問等級

元組類型的訪問等級比較嚴格碎乃,如果它由兩個不同類型組成姊扔,一個是 private ,一個是internal,那么它們組合成的元組類型的訪問等級將是 private

定義訪問等級的原則

定義一個實體時梅誓,這個實體的訪問等級恰梢,不能高于它所參照的實體的訪問等級 :

  • 一個公共變量,不能被定義為internal, fileprivateprivate類型梗掰,因為在這個公共變量使用的地方嵌言,這些類型并不一定都是有效的
  • 一個函數(shù)的訪問等級,不能高于它的參數(shù)類型和返回類型的訪問等級及穗,比如下面的函數(shù)摧茴,分析一下,該用哪種訪問等級 埂陆?
func someFunction() -> (SomeInternalClass, SomePrivateClass) {
    // function implementation goes here
}

可以看到苛白,它的返回類型是個元組類型,這個元組類型最終的訪問等級將是private(至于為什么會是private 請參考上面的元組的訪問等級)焚虱。根據(jù)原則购裙,這個函數(shù)要使用 private 修飾。

private func someFunction() -> (SomeInternalClass, SomePrivateClass) {
    // function implementation goes here
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末鹃栽,一起剝皮案震驚了整個濱河市躏率,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌民鼓,老刑警劉巖薇芝,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異丰嘉,居然都是意外死亡恩掷,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門供嚎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事克滴”普” “怎么了?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵劝赔,是天一觀的道長誓焦。 經常有香客問我,道長着帽,這世上最難降的妖魔是什么杂伟? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮仍翰,結果婚禮上赫粥,老公的妹妹穿的比我還像新娘。我一直安慰自己予借,他們只是感情好越平,可當我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著灵迫,像睡著了一般秦叛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瀑粥,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天挣跋,我揣著相機與錄音,去河邊找鬼狞换。 笑死避咆,一個胖子當著我的面吹牛,可吹牛的內容都是我干的哀澈。 我是一名探鬼主播牌借,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼割按!你這毒婦竟也來了膨报?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤适荣,失蹤者是張志新(化名)和其女友劉穎现柠,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體弛矛,經...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡够吩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了丈氓。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片周循。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡强法,死狀恐怖,靈堂內的尸體忽然破棺而出湾笛,到底是詐尸還是另有隱情饮怯,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布嚎研,位于F島的核電站蓖墅,受9級特大地震影響,放射性物質發(fā)生泄漏临扮。R本人自食惡果不足惜论矾,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望杆勇。 院中可真熱鬧贪壳,春花似錦、人聲如沸靶橱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽关霸。三九已至传黄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間队寇,已是汗流浹背膘掰。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留佳遣,地道東北人识埋。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像零渐,于是被迫代替她去往敵國和親窒舟。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內容

  • 訪問控制(Access Control) 本文內容包括: 模塊和源文件 訪問級別 訪問級別的基本原則默認訪問級別S...
    果啤閱讀 1,197評論 0 1
  • 136.泛型 泛型代碼讓你可以寫出靈活,可重用的函數(shù)和類型,它們可以使用任何類型,受你定義的需求的約束诵盼。你可以寫出...
    無灃閱讀 1,466評論 0 4
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理惠豺,服務發(fā)現(xiàn),斷路器风宁,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • 過去的溫情讓人輾轉難眠洁墙。 又期盼著當下有無數(shù)個不能說的秘密。
    池面船長閱讀 132評論 0 0
  • 今天26歲生日戒财,很平淡热监、很平常的日子,就當一個新的開始吧饮寞,“常與同好爭高下孝扛,不與傻瓜論長短”少和同事爭點有的沒的列吼,...
    哎喲昨天閱讀 195評論 0 0