常见的场景就不说了,说一下注意点
-
open:
只能用在类或者类的成员属性、方法上,不能用在类的初始化器上,也不能用在枚举、结构体上。 -
初始化器:
-
类跨模块调用类的初始化器:
如果一个public/open类
想在另一个模块调用初始化器
(包括编译生成的默认无参初始化器),必须显式提供public的无参初始化器。
原因: 低于public权限则初始化器无法跨模块访问,初始化最高权限是public,无法用open修饰。 -
类的required初始化器:
required初始化器的访问级别必须大于等于它所属类的访问级别。 -
结构体初始化器:
如果结构体
有private\fileprivate
的存储实例属性,并且此存储实例属性的类型在调用处无访问权限,那么它的成员初始化器也是private\fileprivate,否则默认就是internal。
-
-
枚举:
- 不能给
enum
的每个case
单独设置访问级别,每个case
自动接收enum
的访问级别。
举例:
public enum
的定义的case
也是public
的。 - 不能给
-
协议:
-
协议中定义的要求
自动接收协议的访问级别,不能单独设置访问级别,public协议定义的要求也是public -
协议实现
的访问级别必须 ≥ 类型的访问级别,或者
≥ 协议的访问级别
可以这么理解: 如果从类的角度考虑,想访问类中的该协议实现方法
,则必须 ≥ 该类的类型的访问级别;如果从协议实现的角度考虑,则必须能访问到此协议的要求,访问级别必须 ≥ 协议的访问级别。
举例:
// 这里可以编译通过 public protocol Runnable { func run() } class Person: Runnable { func run() { } } // 这里编辑不通过,Person的run()默认internal的 public protocol Runnable { func run() } public class Person: Runnable { func run() { } }
-
-
扩展:
-
如果有显式设置扩展的访问级别,扩展添加的成员自动接收扩展的访问级别
-
如果没有显式设置扩展的访问级别,扩展添加的成员的默认访问级别,跟直接在类型中定义的成员一样
-
可以单独给扩展添加的成员设置访问级别
-
不能给用于遵守协议的扩展显式设置扩展的访问级别
-
在同一文件中的扩展,可以写成类似多个部分的类型声明
-
在原本的声明中声明一个私有成员,可以在同一文件的扩展中访问它
-
在扩展中声明一个私有成员,可以在同一文件的其他扩展中、原本声明中访问它
-
//以下代码编译不报错 public class Person { private func run0() {} private func eat0() { run1() } } extension Person { private func run1() {} private func eat1() { run0() } } extension Person { private func eat2() { run1() } }
-