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() }