和其他高级语言一样Swift中也有访问控制,在Swift中提供了private
、internal
、public
三种访问级别,但是不同的是Swift中的访问级别是基于模块(module
,或者target
)和源文件(.swift
文件)的,而不是基于类型、命名空间声明。
private
: 只能访问当前源文件中的实体(注意Swift
中的private
和其他语言不太一样,它是基于源文件的,作用范围是整个源文件,如果一个源文件中有两个类,那么一个类可以访问另外一个类的私有成员)。
internal
: 可以访问当前模块中的其他任何实体,但是在模块外无法访问,这是所有实体的默认访问级别(通常在一个单目标Application
中不需要自行设置访问级别)。
public
: 可以访问当前模块及其他模块中的任何实体(通常用于Framework
)。
下面是关于Swift
关于不同成员访问级别的约定规则:
- 如果一个类的访问级别是
private
那么该类的所有成员都是private
(此时成员无法修改访问级别),如果一个类的访问级别是internal
或者public
那么它的所有成员都是internal
(如果类的访问级别是public,成员默认internal,此时可以单独修改成员的访问级别),类成员的访问级别不能高于类的访问级别(注意:嵌套类型的访问级别也符合此条规则); - 常量、变量、属性、下标脚本访问级别低于其所声明的类型级别,并且如果不是默认访问级别
(internal)
要明确声明访问级别(例如一个常量是一个private
类型的类类型,那么此常量必须声明为private
); - 在不违反1、2两条规则的情况下,
setter
的访问级别可以低于getter
的访问级别(例如一个属性访问级别是internal
,那么可以添加private(set)
修饰将setter
权限设置为private
,在当前模块中只有此源文件可以访问,对外部是只读的); - 必要构造方法(
required
修饰)的访问级别必须和类访问级别相同,结构体的默认逐一构造函数的访问级别不高于其成员的访问级别(例如一个成员是private
那么这个构造函数就是private
,但是可以通过自定义来声明一个public
的构造函数),其他方法(包括其他构造方法和普通方法)的访问级别遵循规则1; - 子类的访问级别不高于父类的访问级别,但是在遵循三种访问级别作用范围的前提下子类可以将父类低访问级别的成员重写成更高的访问级别(例如父类A和子类B在同一个源文件,A的访问级别是
public
,B的访问级别是internal
,其中A有一个private
方法,那么A可以覆盖其private
方法并重写为internal
); - 协议中所有必须实现的成员的访问级别和协议本身的访问级别相同,其子协议的访问级别不高于父协议;
- 如果一个类继承于另一个类的同时实现了某个协议那么这个类的访问级别为父类和协议的最低访问级别,并且此类中方法访问级别和所实现的协议中的方法相同;
- 扩展的成员访问级别遵循规则1,但是对于类、结构体、枚举的扩展可以明确声明访问级别并且可以更低(例如对于
internal
的类,你可以声明一个private
的扩展),而协议的访问级别不可以明确声明; - 元组的访问级别是元组中各个元素的最低访问级别,注意:元组的访问级别是自动推导的,无法直接使用以上三个关键字修饰其访问级别;
- 函数的访问级是函数的参数、返回值的最低级别,并且如果其访问级别和默认访问级别
(internal)
不符需要明确声明; - 枚举成员的访问级别等同于枚举的访问级别(无法单独设置),同时枚举的原始值、关联值的访问级别不能低于枚举的访问级别;
- 泛型类型或泛型函数的访问级别是泛型类型、泛型函数、泛型类型参数三者中最低的一个;
- 类型别名的访问级别不能高于原类型的访问级别;
网友评论