一币绩、訪問(wèn)控制(Access Control)
- Swift提供了5個(gè)不同的訪問(wèn)級(jí)別(以下是從高到底排列迎变,實(shí)體指被訪問(wèn)級(jí)別修飾的內(nèi)容)
- open:允許在定義實(shí)體的模塊、其他模塊訪問(wèn)氛谜,允許被其他模塊進(jìn)行繼承君账、重寫(xiě)(open只能用在類、類的成員上) 服鹅;
- public:允許在定義實(shí)體的模塊凳兵、其他模塊中訪問(wèn),不允許被其他模塊進(jìn)行繼承企软、重寫(xiě)庐扫;
- internal:只允許在定義實(shí)體的模塊中訪問(wèn),不允許其他模塊中訪問(wèn);
- fileprivate:只允許在定義實(shí)體的源文件中訪問(wèn)(相當(dāng)于當(dāng)前類)形庭;
- private:只允許在定義實(shí)體的封閉聲明中訪問(wèn)铅辞;
二、訪問(wèn)級(jí)別的使用準(zhǔn)則
- 一個(gè)實(shí)體不可以被更低訪問(wèn)級(jí)別的實(shí)體定義萨醒,比如:
- 變量斟珊、常量類型 >= 變量、常量
- 參數(shù)類型富纸、返回值類型 >= 函數(shù)
- 父類 >= 子類
- 父協(xié)議 >= 子協(xié)議
- 原類型 >= typealias
- 原始值類型囤踩、關(guān)聯(lián)值類型 >= 枚舉類型
- 定義類型A時(shí)用到的其他類型 >= A類型
private class Car {
var name: String?
func testP() {
}
}
//Variable must be declared private or fileprivate because its type uses a private type
var c: Car?
// 相當(dāng)于別定義的c的訪問(wèn)權(quán)限不大于Car的訪問(wèn)權(quán)限
- 總之:一個(gè)類型在定義時(shí)不會(huì)大于定義它的實(shí)體類型
三、元組晓褪、泛型類型
- 元組類型的訪問(wèn)級(jí)別是所有成員類型最低的那個(gè)
fileprivate class Car {
}
internal class Dog {
}
// 這里會(huì)報(bào)錯(cuò)
internal var data1 : (Dog, Car)
// 這里的訪問(wèn)級(jí)別是fileprivate堵漱、
- 就是會(huì)根據(jù)最低的那個(gè)訪問(wèn)級(jí)別確定總的訪問(wèn)級(jí)別
- 泛型類型的訪問(wèn)級(jí)別是 類型的訪問(wèn)級(jí)別 以及所有泛型類型參數(shù)的訪問(wèn) 解包中最低的那個(gè)
四、成員涣仿、嵌套類型
- 類型的訪問(wèn)級(jí)別會(huì)影響成員(屬性勤庐、下標(biāo)、方法好港、初始化器)愉镰、嵌套類型的默認(rèn)訪問(wèn)級(jí)別
- 一般情況下,類型為private或者fileprivate钧汹,那么成員丈探、嵌套類型默認(rèn)也是private、fileprivate
- 一般情況下崭孤,類型為internal或public类嗤,那么成員、嵌套類型默認(rèn)為internal
public class Car {
public var p1 = 0 // public
var p2 = 0 // internal
}
internal class Dog {
var name: String? // internal
private func f1() {} // private
}
五辨宠、成員的重寫(xiě)
- 子類重寫(xiě)成員的訪問(wèn)級(jí)別必須 >= 子類的訪問(wèn)級(jí)別遗锣,或者>=父類被重寫(xiě)成員的訪問(wèn)級(jí)別
public class Person {
fileprivate var p1 = 0
}
class Student : Person {
override var p1: Int { // internal
set {}
get { 10 }
}
}
- 父類的成員不能被成員作用域外定義的子類重寫(xiě)
public class Person {
private var p1 = 0
class Student : Person {
override var p1: Int { // internal
set {}
get { 10 }
}
}
}
- 總之成員重寫(xiě)后的訪問(wèn)權(quán)限是不小于之前的訪問(wèn)權(quán)限
- 直接在全局作用域下定義的private等價(jià)于fileprivate
六、getter嗤形、setter方法默認(rèn)自動(dòng)接收他們所屬環(huán)境的訪問(wèn)級(jí)別
- 可以給setter單獨(dú)設(shè)置一個(gè)比getter更低的訪問(wèn)級(jí)別精偿,用來(lái)限制寫(xiě)的權(quán)限
// 這句話是說(shuō)set的權(quán)限是fileprivate、getter的權(quán)限是public
fileprivate(set) public var num = 10
七赋兵、初始化器
- 如果一個(gè)public類想在另一個(gè)模塊調(diào)用編譯生成的默認(rèn)初始化器笔咽,必須顯示提供public的無(wú)參初始化器
- 因?yàn)閜ublic的默認(rèn)初始化器是internal級(jí)別
- required初始化器 >= 它的默認(rèn)訪問(wèn)級(jí)別
- 如果結(jié)構(gòu)體有private、fileprivate的存儲(chǔ)實(shí)例屬性霹期,那么它的成員初始化器也是private叶组、fileprivate
- 否則就是internal
八、枚舉類型的case
- 補(bǔ)鞥呢給enum的每個(gè)case單獨(dú)設(shè)置訪問(wèn)級(jí)別
- 每個(gè)case自動(dòng)接收enum的訪問(wèn)級(jí)別
- public enum定義的case也是public
public enum Shape {
case circle, triangle, square // public
}
九历造、協(xié)議
- 協(xié)議中定義的要求自動(dòng)接收協(xié)議的訪問(wèn)級(jí)別甩十,不能單獨(dú)設(shè)置訪問(wèn)級(jí)別
- public 協(xié)議定義的要求也是public
- 協(xié)議實(shí)現(xiàn)的訪問(wèn)級(jí)別 >= 類型的訪問(wèn)級(jí)別船庇,或者 >= 協(xié)議的訪問(wèn)級(jí)別
public protocol Run { func ru() }
public class Car : Run {
// 這里會(huì)報(bào)錯(cuò)、因?yàn)槟J(rèn)的訪問(wèn)級(jí)別是internal侣监、而協(xié)議的是public
func ru() {
}
}
十鸭轮、擴(kuò)展
- 如果有顯式設(shè)置擴(kuò)展的訪問(wèn)級(jí)別,擴(kuò)展添加的成員自動(dòng)接收擴(kuò)展的訪問(wèn)級(jí)別
- 如果沒(méi)有顯式設(shè)置擴(kuò)展的訪問(wèn)級(jí)別橄霉,擴(kuò)展添加的成員的默認(rèn)訪問(wèn)級(jí)別窃爷,跟直接在類型中定義的成員一致
- 可以單獨(dú)給擴(kuò)展添加的成員設(shè)置訪問(wèn)級(jí)別
- 不能給用于遵守協(xié)議的擴(kuò)展顯式設(shè)置擴(kuò)展訪問(wèn)級(jí)別
- 在同一文件中的擴(kuò)展,可以寫(xiě)成類似多個(gè)部分的類型聲明
- 在原本的聲明中聲明一個(gè)私有成員姓蜂,可以在同一文件的擴(kuò)展中訪問(wèn)它
- 在擴(kuò)展中聲明的私有成員按厘,可以在同一文件的其他擴(kuò)展中、原本聲明中訪問(wèn)它
public class Person {
private func run() {}
private func eat() {}
}
extension Person {
private func run1 {}
private func eat1() {
eat()
}
}
至此钱慢、swift訪問(wèn)控制基本說(shuō)完刻剥,如有不當(dāng)之處、還請(qǐng)各位大佬批評(píng)指正滩字,不勝感激!