18-訪問控制

訪問控制(Access Control)

在訪問權(quán)限控制這塊,Swift提供了5個不同的訪問級別(以下是從高到低排列芳杏, 實體指被訪問級別修飾的內(nèi)容)
  • open:允許在定義實體的模塊、其他模塊中訪問狞贱,允許其他模塊進行繼承坛悉、重寫(open只能用在類罐脊、類成員上)
  • public:允許在定義實體的模塊、其他模塊中訪問枯怖,不允許其他模塊進行繼承注整、重寫
  • internal:只允許在定義實體的模塊中訪問,不允許在其他模塊中訪問
  • fileprivate:只允許在定義實體的源文件中訪問
  • private:只允許在定義實體的封閉聲明中訪問
  • 絕大部分實體默認都是internal 級別

訪問級別的使用準則

一個實體不可以被更低訪問級別的實體定義度硝,比如
  • 變量\常量類型≥ 變量\常量
  • 參數(shù)類型肿轨、返回值類型≥ 函數(shù)
  • 父類≥ 子類
  • 父協(xié)議≥ 子協(xié)議
  • 原類型≥ typealias
  • 原始值類型、關聯(lián)值類型≥ 枚舉類型
  • 定義類型A時用到的其他類型≥ 類型A
  • ......

元組類型

  • 元組類型的訪問級別是所有成員類型最低的那個
internal struct Dog {}
fileprivate class Person {}

// (Dog, Person)的訪問級別是fileprivate
fileprivate var data1: (Dog, Person)
private var data2: (Dog, Person)

泛型類型

  • 泛型類型的訪問級別是類型的訪問級別以及所有泛型類型參數(shù)的訪問級別中最低的那個
internal class Car {}
fileprivate class Dog {}
public class Person<T1, T2> {}

// Person<Car, Dog>的訪問級別是fileprivate
fileprivate var p = Person<Car, Dog>()

成員蕊程、嵌套類型

  • 類型的訪問級別會影響成員(屬性椒袍、方法、初始化器藻茂、下標)晋柱、嵌套類型的默認訪問級別
  • 一般情況下,類型為private或fileprivate焦影,那么成員\嵌套類型默認也是private或fileprivate
  • 一般情況下胞谈,類型為internal或public,那么成員\嵌套類型默認是internal
public class PublicClass {
    public var p1 = 0 // public
    var p2 = 0 // internal
    fileprivate func f1() {} // fileprivate
    private func f2() {} // private
}
class InternalClass { // internal
    var p = 0 // internal
    fileprivate func f1() {} // fileprivate
    private func f2() {} // private
}
fileprivate class FilePrivateClass { // fileprivate
    func f1() {} // fileprivate
    private func f2() {} // private
}
private class PrivateClass { // private
    func f() {} // private
}

成員的重寫

  • 子類重寫成員的訪問級別必須≥ 子類的訪問級別肖油,或者≥ 父類被重寫成員的訪問級別
  • 父類的成員不能被成員作用域外定義的子類重寫
public class Person {
    private var age: Int = 0
}
public class Student : Person {
    override var age: Int {
        set {}
        get {10}
    }
}
public class Person {
    private var age: Int = 0
    public class Student : Person {
        override var age: Int {
            set {}
            get {10}
        }
    }
}

下面代碼能否編譯通過兼吓?

private class Person {}
fileprivate class Student : Person {}
private struct Dog {
    var age: Int = 0
    func run() {}
}
fileprivate struct Person {
    var dog: Dog = Dog()
    mutating func walk() {
        dog.run()
        dog.age = 1
    }
}
private struct Dog {
    private var age: Int = 0
    private func run() {}
}
fileprivate struct Person {
    var dog: Dog = Dog()
    mutating func walk() {
        dog.run()
        dog.age = 1
    }
}
  • 直接在全局作用域下定義的private等價于fileprivate

getter、setter

  • getter森枪、setter默認自動接收它們所屬環(huán)境的訪問級別
  • 可以給setter單獨設置一個比getter更低的訪問級別视搏,用以限制寫的權(quán)限
fileprivate(set) public var num = 10
class Person {
    private(set) var age = 0
    fileprivate(set) public var weight: Int {
        set {}
        get { 10 }
    }
    internal(set) public subscript(index: Int) -> Int {
        set {}
        get { index }
    }
}

初始化器

  • 如果一個public類想在另一個模塊調(diào)用編譯生成的默認無參初始化器审孽,必須顯式提供public的無參初始化器
    因為public類的默認初始化器是internal級別

  • required初始化器≥ 它的默認訪問級別

  • 如果結(jié)構(gòu)體有private\fileprivate的存儲實例屬性,那么它的成員初始化器也是private\fileprivate
    否則默認就是internal

枚舉類型的case

  • 不能給enum的每個case單獨設置訪問級別

  • 每個case自動接收enum的訪問級別
    public enum定義的case也是public

協(xié)議

  • 協(xié)議中定義的要求自動接收協(xié)議的訪問級別浑娜,不能單獨設置訪問級別
    public協(xié)議定義的要求也是public

  • 協(xié)議實現(xiàn)的訪問級別必須≥ 類型的訪問級別佑力,或者≥ 協(xié)議的訪問級別

  • 下面代碼能編譯通過么?

public protocol Runnable {
    func run()
}
public class Person : Runnable {
    func run() {}
}

擴展

  • 如果有顯式設置擴展的訪問級別筋遭,擴展添加的成員自動接收擴展的訪問級別

  • 如果沒有顯式設置擴展的訪問級別打颤,擴展添加的成員的默認訪問級別,跟直接在類型中定義的成員一樣

  • 可以單獨給擴展添加的成員設置訪問級別

  • 不能給用于遵守協(xié)議的擴展顯式設置擴展的訪問級別

擴展

  • 在同一文件中的擴展漓滔,可以寫成類似多個部分的類型聲明
    在原本的聲明中聲明一個私有成員编饺,可以在同一文件的擴展中訪問它
    在擴展中聲明一個私有成員,可以在同一文件的其他擴展中响驴、原本聲明中訪問它
public class Person {
    private func run0() {}
    private func eat0() {
        run1()
    }
}
extension Person {
    private func run1() {}
    private func eat1() {
        run0()
    }
}
extension Person {
    private func eat2() {
        run1()
    }
}

將方法賦值給var\let

  • 方法也可以像函數(shù)那樣透且,賦值給一個let或者var
struct Person {
    var age: Int
    func run(_ v: Int) { print("func run", age, v) }
    static func run(_ v: Int) { print("static func run", v) }
}

let fn1 = Person.run
fn1(10) // static func run 10

let fn2: (Int) -> () = Person.run
fn2(20) // static func run 20

let fn3: (Person) -> ((Int) -> ()) = Person.run
fn3(Person(age: 18))(30) // func run 18 30
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市豁鲤,隨后出現(xiàn)的幾起案子秽誊,更是在濱河造成了極大的恐慌,老刑警劉巖琳骡,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锅论,死亡現(xiàn)場離奇詭異,居然都是意外死亡楣号,警方通過查閱死者的電腦和手機最易,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來竖席,“玉大人耘纱,你說我怎么就攤上這事”霞觯” “怎么了束析?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長憎亚。 經(jīng)常有香客問我员寇,道長,這世上最難降的妖魔是什么第美? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任蝶锋,我火速辦了婚禮,結(jié)果婚禮上什往,老公的妹妹穿的比我還像新娘扳缕。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布躯舔。 她就那樣靜靜地躺著驴剔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪粥庄。 梳的紋絲不亂的頭發(fā)上丧失,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機與錄音惜互,去河邊找鬼布讹。 笑死,一個胖子當著我的面吹牛训堆,可吹牛的內(nèi)容都是我干的描验。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼蔫慧,長吁一口氣:“原來是場噩夢啊……” “哼挠乳!你這毒婦竟也來了权薯?” 一聲冷哼從身側(cè)響起姑躲,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎盟蚣,沒想到半個月后黍析,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡屎开,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年阐枣,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奄抽。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡蔼两,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出逞度,到底是詐尸還是另有隱情额划,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布档泽,位于F島的核電站俊戳,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏馆匿。R本人自食惡果不足惜抑胎,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望渐北。 院中可真熱鬧阿逃,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至淡喜,卻和暖如春秕磷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背炼团。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工澎嚣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瘟芝。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓易桃,卻偏偏與公主長得像,于是被迫代替她去往敵國和親锌俱。 傳聞我的和親對象是個殘疾皇子晤郑,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 在訪問控制這塊,Swift提供了五個不同的訪問級別(以下是從高到低排列贸宏,實體指被訪問級別修飾的內(nèi)容) open :...
    西風那個吹呀吹閱讀 1,133評論 0 2
  • 訪問控制 在訪問權(quán)限控制這塊,Swift提供了5個不同的訪問級別鲫咽,以下是從高到低的敘述签赃,其中實體是指被訪問級別修飾...
    YanZi_33閱讀 256評論 0 0
  • 中文文檔 一、模塊和源文件 Swift 中的訪問控制模型基于模塊和源文件這兩個概念分尸。 模塊指的是獨立的代碼單元锦聊,框...
    伯wen閱讀 297評論 0 0
  • 一、訪問控制(Access Control) Swift提供了5個不同的訪問級別(以下是從高到底排列箩绍,實體指被訪問...
    alfei13閱讀 294評論 0 0
  • 訪問控制 可以限定其它源文件或模塊中的代碼對你的代碼的訪問級別孔庭。這個特性可以讓我們隱藏代碼的一些實現(xiàn)細節(jié),并且可以...
    答案MK閱讀 268評論 0 0