訪問限制可以限定其他源文件或模塊中代碼對你的代碼的訪問級別越除。
你可以明確的給單個類型(類,結構體外盯,枚舉)設置訪問級別摘盆,也可以給這些類型的屬性、函數饱苟、初始化方法孩擂、基本類型、下標索引等設置訪問級別
協(xié)議也可以被限定在一定范圍內使用掷空,包裹協(xié)議中的全部常量肋殴、變量和函數。
訪問控制基于模塊和源文件坦弟。
模塊指的是以獨立單元構建和發(fā)布的 Framework 或 Applicaiton护锤。Swift中的一個模塊可以使用Import關鍵字引入另外一個模塊
源文件是單個源碼文件,它通常屬于一個模塊酿傍,源文件可以包含多個類和函數的定義
Swift提供四種不用訪問級別:public烙懦、internal、filePrivate赤炒、private.
訪問級別 | 定義 |
---|---|
public | 可以訪問自己模塊中源文件里的任何實體氯析,別人也可以通過引入該模塊來訪問源文件離得所有實體 |
interna | 可以訪問自己模塊中源文件里的任何實體亏较,但是別人不能訪問該模塊中源文件里的實體 |
fileprivate | 文件內私有 ,只能在當前文件中使用 |
private | 只能在類中訪問掩缓,離開這個內或者結構體的作用域外面就無法訪問 |
public為最高訪問級別雪情,private為最低訪問級別
通過修飾符public、internal你辣、fileprivate巡通、private來聲明實體的訪問級別:
public class SomePublicClass {}
internal class SomeInternalClass {}
fileprivate class SomeFilePrivateClass {}
private class SomePrivateClass()
public var somePublicVariable = 0
internal let someInternalConstant = 0
fileprivate func someFilePrivateFunction() {}
private func somePrivateFunction() {}
除非有特殊的說明,否則實體都使用默認的訪問級別 internal舍哄。
函數類型訪問限制
函數的訪問級別需要根據該函數的參數類型和返回類型的訪問級別得出宴凉。
func someFunction() -> (SomeInternalClass,SomePrivateClass) {
//函數實現
}
該函數神明為為public或internal,或者使用默認的internal都是錯誤的表悬,因為如果這樣你就無法訪問private級別的返回值弥锄。
枚舉類型訪問權限
枚舉中成員的訪問級別繼承自該枚舉,你不能為枚舉中成員單獨申明不同的訪問級別蟆沫。
比如下面的例子籽暇,枚舉 Student 被明確的申明為 public 級別,那么它的成員 Name饭庞,Mark 的訪問級別同樣也是 public:
public enum Student {
case Name(String)
case Mark(Int,Int,Int)
}
var studDetails = Student.Name("Swift")
var studMarks = Student.Mark(98,97,95)
switch studMarks {
case .Name(let studName):
print("學生名: \(studName).")
case .Mark(let Mark1, let Mark2, let Mark3):
print("學生成績: \(Mark1),\(Mark2),\(Mark3)")
}
以上程序執(zhí)行輸出結果為:
學生成績: 98,97,95
子類訪問權限
子類的訪問級別不得高于父類的訪問級別图仓。比如說,父類的訪問級別是internal但绕,子類的訪問級別就不能申明為public救崔。
public class SuperClass {
fileprivate func show() {
print("超類")
}
}
// 訪問級別不能低于超類 internal > public
internal class SubClass: SuperClass {
override internal func show() {
print("子類")
}
}
let sup = SuperClass()
sup.show()
let sub = SubClass()
sub.show()
以上程序執(zhí)行輸出結果為:
超類
子類
常量、變量捏顺、屬性六孵、下標
常量、變量幅骄、屬性不能擁有比它們的類型更高的訪問級別劫窒。
比方說神年,你定義一個public級別的屬性窍奋,但是它們的類型是private級別的,這是編譯器不允許的碱蒙。
同樣下標也不能擁有比索引類型或返回類型更高的訪問級別挪凑。
如果常量孕索、變量、屬性躏碳、下標索引的定義類型是private級別的搞旭,那么它們必須明確申明訪問級別為private:
private var privateInstance = SomePrivateClass()
Getter 和 Setter訪問權限
常量、變量、屬性肄渗、下標索引的Getter和Setter的訪問級別繼承自它們所屬成員的訪問變量镇眷。
Setter的訪問級別可以抵御對應的Getter的訪問級別。這樣可以控制變量翎嫡、屬性或下標索引的讀寫權限欠动。
class Samplepgm {
fileprivate var counter: Int = 0{
willSet(newTotal){
print("計數器: \(newTotal)")
}
didSet{
if counter > oldValue {
print("新增加數量 \(counter - oldValue)")
}
}
}
}
let NewCounter = Samplepgm()
NewCounter.counter = 100
NewCounter.counter = 800
counter的訪問級為filePrivate,在文件內可以訪問。
以上程序輸出的結果為:
計數器: 100
新增加數量 100
計數器: 800
新增加數量 700
構造默認設置器
初始化:我們可以給自定義的初始化方法申明訪問級別惑申,但是要不高于所屬類的訪問級別翁垂。但必要構造器除外,它的訪問級別必須和所屬類的訪問級別相同硝桩。
如同函數或方法參數,初始化方法參數的訪問級別也不能低于初始化方法的級別枚荣。
默認初始化方法:Swift為結構體碗脊、類提供了一個默認的無參初始化方法,用于給它們的所有屬性提供賦值操作橄妆,但不會給出具體值衙伶。默認初始化方法的訪問級別與所屬類型的訪問級別相同。
在每個子類的 init() 方法前使用 required 關鍵字聲明訪問權限害碾。
class classA {
required init() {
var a = 10
print(a)
}
}
class classB: classA {
required init() {
var b = 30
print(b)
}
}
let res = classA()
let show = classB()
輸出結果為:
10
30
10
協(xié)議類型訪問限制
如果你想為協(xié)議聲明訪問級別矢劲,那么需要注意的是你要確保該協(xié)議只在你你聲明的訪問級別的作用域中使用。
如果你定義了一個public訪問級別的協(xié)議慌随,那么實現該協(xié)議提供的必要函數也會是public的訪問級別芬沉。這一點不同于其他類型,其他級別可以比public低阁猜。
public protocol TcpProtocol {
init(no1: Int)
}
public class MainClass {
var no1: Int // local storage
init(no1: Int) {
self.no1 = no1 // initialization
}
}
class SubClass: MainClass, TcpProtocol {
var no2: Int
init(no1: Int, no2 : Int) {
self.no2 = no2
super.init(no1:no1)
}
// Requires only one parameter for convenient method
required override convenience init(no1: Int) {
self.init(no1:no1, no2:0)
}
}
let res = MainClass(no1: 20)
let show = SubClass(no1: 30, no2: 50)
print("res is: \(res.no1)")
print("res is: \(show.no1)")
print("res is: \(show.no2)")
輸出結果為:
res is: 20
res is: 30
res is: 50
擴展訪問權限
你可以在條件允許的情況下對類丸逸、結構體、枚舉進行擴展剃袍,擴展成員應該具有和原始類成員一致的訪問級別黄刚。比如你擴展了一個公共類型,那么你新加的成員應該具有和原始成員一樣的默認internal訪問級別民效。
或者你可以明確聲明擴展的訪問級別(比如使用private extension)給擴展所有成員變量設置默認訪問級別憔维。這個新的默認訪問級別仍然可以被單獨成員聲明的訪問級別所覆蓋。
泛型訪問權限
泛型類型或泛型函數的訪問級別去泛型類型畏邢、函數本身业扒、反省類型參數三者中的最低訪問級別。
類型別名
任何你定義的類型別名都會被當做不同的類型舒萎,以便于進行訪問控制凶赁。一個類型別名的訪問級別不可高于原類型的訪問級別。
比如說一個private級別的類型可以設定為public、internal虱肄、private的類型致板,但是一個public級別的類型別名只能是一個public級別的別名的類型,不能設定比public 級別低或高的類型咏窿。
注意:這條規(guī)則也適用于滿足協(xié)議一致性而給相關類型命名別名情況斟或。