-
实体:
代码中可以设置访问级别的特性(属性、基本类型、函数等)
-
模块:
框架或应用程序会作为一个独立的模块来构建和发布.不同模块,需要使用import
导入.例子:通过"Xcode"创建的APP工程
-
源文件:
模块内的代码文件.例子:工程内的某一个".swift"文件,同一个模块内,源文件之间可以互相调用,不需要导入
-
访问控制:Swift为实体提供了5个访问级别
-
open
:优先级最高,能被任何模块访问,能被其他模块继承并重写 -
public
:优先级次之,能被任何模块访问,不能被其他模块继承并重写 -
internal
:只能在模块内访问,不能被外部模块访问 -
fileprivate
:只能在所定义的文件里访问,注意,Swift3.0才有该关键字 -
private
:只能在定义域里访问
-
-
Swift中,实体的默认级别为
internal
-
访问级别基本原则
- 不可以在某个实体中定义访问级别更低(更严格)的实体
- 一个公开访问级别的变量,其类型的访问级别不能是内部,文件私有或是私有类型的。因为无法保证变量的类型在使用变量的地方也具有访问权限。
- 函数的访问级别不能高于它的参数类型和返回类型的访问级别。因为这样就会出现函数可以在任何地方被访问,但是它的参数类型和返回类型却不可以的情况。
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() {}
- 如果一个类的访问级别是
private
,那么他的成员访问级别也是private
,如果是public
,那么他的成员级别是internal
-
元组:
- 不可以在某个实体中定义访问级别更低(更严格)的实体
元组的访问级别由存入值中,访问级别最低的实体决定
- ###函数:
函数的访问级别,由它的参数或者返回类型来决定,且不会隐式转换,可以看到,我们定义了两个类,一个方法,方法返回值是一个元组,上面我们提到元组的访问级别由最低的实体决定,所以放回参数的访问级别为private
,这时候如果我们不对方法限制,方法的默认级别为internal
,则会引起报错
internal class SomeInternalClass {} private class SomePrivateClass {} //报错 //func someFunction() -> (SomeInternalClass, SomePrivateClass) { // return (SomeInternalClass(),SomePrivateClass()) //} private func anotherFunction() -> (SomeInternalClass, SomePrivateClass) { return (SomeInternalClass(),SomePrivateClass()) }
- ###枚举:
枚举的每个事件的访问级别,与枚举的访问级别相同,枚举的原始值类型的访问级别不能低于枚举的访问级别
public typealias A = Int public enum AnEnum:A { case A = 0 case B case C } //报错,因为枚举时public类型,而类型private private typealias B = Int //public enum AotherEnum:B { // case A = 0 // case B // case C //}
- ###嵌套类型:
嵌套类型中,如果外部是public
类型,嵌套的类型为internal
,其他的访问级别,与外部访问级别一致
- ###子类:
子类的访问级别不能高于父类,但子类能通过重写父类的方法与属性来改变访问级别
internal class ClassA { private var num:Int { return 1 } } //报错,子类访问级别不能高于父类 //public class ClassB:ClassA { // //} class ClassB:ClassA { override internal var num :Int{ return 3 } }
- ###常量,变量,属性,下标:
变量常量的访问级别不能高于实例对应类型的访问级别,属性,下标的访问级别也不可高于所在的类,
private class ClassA { //报警告 public var name = "" //报警告 public subscript(index:String) -> String { return "a" } } //报错,变量常量的访问级别不能高于实例对应类型的访问级别 //public var classA = ClassA()
- ###getter,setter:
我们可以通过调低属性的setter
访问级别,使属性在外部变为只读属性.我们也可以同时设置属性的setter,getter
的访问属性
struct TrackedString { internal private(set) var numberOfEdits = 0 var value: String = "" { didSet { numberOfEdits += 1 } } }
- ###构造器:
必要构造器的访问级别必须与它所在类型的访问级别相同,自定义构造器访问级别可以低于所在类
class ClassA { // //报错,必要构造器的访问级别过低 // private required init (name:String) { // // } private init (name:String) { } }
- ###类型别名:
低访问级别的类型不能转换为高访问级别的类型,高访问级别的类型可以随意转换成比其低级别的类型
private class ClassA { } public class ClassB { } //报错,低访问级别的类型不能转换为高访问级别的类型 //public typealias SomeClass = ClassA public typealias AnotherClass = ClassB
网友评论