Swift
中的訪問控制模型基於模塊和源文件這兩個概念swift
Framework
或App bundle
。在Swift
中,能夠用import
關鍵字引入本身的工程。Swift
中的Swift File
,就是編寫Swift
代碼的文件,它一般是屬於某一個模塊。Public
:【使用public
修飾】【範圍大】Framework
)Internal
:【使用internal
修飾】【範圍中】Application
中不須要自行設置訪問級別)Private
:【使用private
修飾】【範圍小】訪問級別從低到高:Private
< Internal
< Public
ide
/* 1.【成員(屬性和方法) <= 類】 若是你將類申明爲private類,那麼該類的全部成員的默認訪問級別也會成爲private 若是你將類申明爲public或者internal類,那麼該類的全部成員默認訪問級別是internal。 */ public class SomePublicClass { // 顯示的public類 public var somePublicProperty = 0 // 顯示的public類成員 var someInternalProperty = 0 // 隱式的internal類成員 internal var someInternalProperty2 = 0 //顯示的internal類成員 private func somePrivateMethod() {} // 顯示的private類成員 } internal class SomeInternalClass { // 顯示的internal類 var someInternalProperty = 0 // 隱式的internal類成員 private func somePrivateMethod() {} // 顯示的private類成員 //Error:-> public var somePublicProperty = 0 } private class SomePrivateClass { // 顯示的private類 var somePrivateProperty = 0 // 隱式的private類成員 func somePrivateMethod() {} // 隱式的private類成員 //Error:-> public var somePublicProperty = 0 //Error:-> internal var someInternalProperty = 0 }
/* 2.【(常量、變量、屬性、下標腳本) <= 本身類型】 */ private let somePrivate1 = SomePrivateClass() //變量爲private <= 類型爲private private let somePrivate2 = SomeInternalClass()//變量爲private <= 類型爲internal private let somePrivate3 = SomePublicClass()//變量爲private <= 類型爲public //Error:internal let someInternal1 = SomePrivateClass() //變量internal大於類型private,錯誤 internal let someInternal2 = SomeInternalClass()//變量爲internal <= 類型爲internal internal let someInternal3 = SomePublicClass()//變量爲internal <= 類型爲public //Error:public let somePublic1 = SomePrivateClass() //變量public大於類型private,錯誤 //Error:public let somePublic2 = SomeInternalClass() //變量public大於類型internal,錯誤 public let somePublic3 = SomePublicClass()//變量爲public <= 類型爲public
/* 3.【setter <= getter】,private(set)修飾將setter權限設置爲private */ /* 這個規定適用於用做存儲的屬性或用做計算的屬性。 即便你不明確的申明存儲屬性的Getter、Setter, Swift也會隱式的爲其建立Getter和Setter,用於對該屬性進行讀取操做。 */ public class SetterPrivateClass {//該類能夠在任何模塊中使用 private(set) var value = 0 //設置存儲屬性的setter爲private //設置計算屬性的setter屬性爲private private(set) var setPrivateProperty:Int { set{//此時setter爲private,也就是隻能在本文件中使用,其餘文件沒法使用 value = newValue + 1 } get{//getter默認爲internal return value + 1 } } }
/* 4.【required修飾的方法 == 類】,(結構體)【默認逐一構造函數 <= 全部成員】 */ protocol RequiredTestProtocol { //初始化構造器要求 init(aprot: Int) } public class RequiredTestClass: RequiredTestProtocol { var aprot: Int //默認爲internal //實現協議的初始化要求時,必須使用required關鍵字確保子類必須也得實現這個構造器 public required init(aprot: Int) {//此時必須設置爲public,由於默認是internal的 self.aprot = aprot } } //該結構體的默認逐一構造方法爲private,但默認構造方法仍是internal public struct StructInitTest{ private var somePrivateProperty = 0 internal var someInternalProperty = 0 public var somePublicProperty = 0 }
/* 5.【子類 <= 父類】,【子協議 <= 父協議】 */ private class PrivateSuperClass { } //private父類 internal class InternalSuperClass { }//internal父類 public class PublicSuperClass { }//public父類 private class PrivateSubClass1:PrivateSuperClass { } //子類private <= private父類 private class PrivateSubClass2:InternalSuperClass { } //子類private <= internal父類 private class PrivateSubClass3:PublicSuperClass { } //子類private <= public父類 //Error:internal class InternalSubClass1:PrivateSuperClass { } //子類internal大於private父類,錯誤 internal class InternalSubClass2:InternalSuperClass { } //子類internal <= internal父類 internal class InternalSubClass3:PublicSuperClass { } //子類internal <= public父類 //Error:public class PublicSubClass1:PrivateSuperClass { } //子類public大於private父類,錯誤 //Error:public class PublicSubClass2:InternalSuperClass { } //子類public大於internal父類,錯誤 public class PublicSubClass3:PublicSuperClass { } //子類public <= public父類
/* 6.不違反前面規則,子類能夠經過重寫父類方法來修改訪問權限範圍 */ public class OverrideSuperClass { private func someMethod() {} } internal class OverrideSubClass: OverrideSuperClass { override internal func someMethod() { super.someMethod()//子類和父類在同一個源文件中,因此能夠訪問super的someMethod()方法 } }
/* 7.【協議全部必須實現的成員 == 協議】,【類 >= 協議】,【協議實現 >= 協議要求】 */ internal protocol InternalProtocol { //協議成員不能夠添加訪問控制關鍵字,默認等於協議的訪問權限範圍 var someProperty:Int { get set } func someMethod() } //類必須大於或等於要遵循的協議 public class ProtocolTestClass:InternalProtocol { //Error:-> private var someProperty = 0 //協議實現必須大於或等於協議要求 public var someProperty = 0 internal func someMethod() { print("ProtocolTestClass someMethod") } }
/* 8.【元組 = Min(全部元素類型)】,注意是類型而不是變量 */ private var privateValue = SomePrivateClass() //注意,看類型訪問級別而不是變量訪問級別 var internalValue = SomeInternalClass() var publicValue = SomePublicClass() //這裏變量是internal的,但類型是public的 private let privateTupleValue = (privateValue, internalValue, publicValue) internal let internalTupleValue = (internalValue, internalValue, publicValue) public let publicTupleValue = (publicValue, publicValue, publicValue)
/* 9.【函數 = Min(參數類型,返回值類型)】 */ private func someFunction(value:SomeInternalClass) -> SomePrivateClass { //函數體 return SomePrivateClass() }
/* 10.【枚舉成員 == 枚舉】,枚舉成員無法單獨設置訪問級別,【(原始值,關聯值) >= 枚舉】 */ private enum PrivateEnum { case PrivateEnumCase( SomePrivateClass ) case InternalEnumCase( SomeInternalClass ) case PublicEnumCase( SomePublicClass ) } internal enum InternalEnum { //Error:-> case PrivateEnumCase( SomePrivateClass ) //關聯值必須大於枚舉 case InternalEnumCase( SomeInternalClass ) case PublicEnumCase( SomePublicClass ) }
/* 11.【泛型類型 = Min(類類型,泛型參數)】 */ public class GenericityClass<T> { var value = [T]() func someFunction(value:T) { } } private let genericityPrivate = GenericityClass<SomePrivateClass>() //泛型類型爲private internal let genericityInternal = GenericityClass<SomeInternalClass>() //泛型類型爲internal public let genericityPublic = GenericityClass<SomePublicClass>() //泛型類型爲public //Error:public let genericityInternal = GenericityClass<SomeInternalClass>() //泛型類型爲internal
/* 12.【類型別名 <= 原類型】 */ //包含類型別名的類,遵循【成員<=類】 public class MyClass { //聲明一個類型別名,類型別名是一個爲已存在類型定義的一個可選擇的名字 private typealias privateName1 = SomePrivateClass private typealias privateName2 = SomeInternalClass private typealias privateName3 = SomePublicClass //internal的類型別名能夠是internal、public的類型,不能夠是private類型 //Error:-> internal typealias internalName1 = SomePrivateClass internal typealias internalName2 = SomeInternalClass internal typealias internalName3 = SomePublicClass //public的類型別名只能是public的類型 //Error:-> public typealias publicName1 = SomePrivateClass //Error:-> public typealias publicName2 = SomeInternalClass public typealias publicName3 = SomePublicClass private var someProperty = privateName1() }