Swift 访问控制等级

Top

  • open: 允许在定义实体的模块、其他模块中访问,允许其他模块进行继承、重写(open只能用在类、类成员上)
  • public: 允许在定义实体的模块、其他模块中访问,不允许其他模块进行继承、重写
  • internal: 只允许在定义实体的模块中访问,不允许在其他模块中访问
  • fileprivate: 只允许在定义实体的源文件中访问
  • private: 只允许在定义实体的封闭声明中访问

绝大部分实体默认都是internal级别

  • 准则1: 低等级的定义不能被高等级的定义包含,并暴露出去
//fileprivate 等级的类
fileprivate class Person {}
public var p : Person //❌ 
public class Jason : Person {} //❌
fileprivate class John : Person {} //正确
  • 准则2: 泛型使用场景中,应该以最低访问等级的那个类型为准。
internal class Car {}
fileprivate class Dog {} //最低等级
public class Person<T1, T2> {}
fileprivate var p = Person<Car, Dog>() //以最低等级为准,该变量必须设定为 fileprivate
  • 准则3: 类型的等级会影响它的函数,变量等访问等级。
fileprivate class Person {
	var age : Int //也是fileprivate
}
  • 准则4: 源码文件最外面的private等同于 fileprivate。
//文件最外层的 private Dog结构,等同于fileprivate等级。
private struct Dog {
    private var age: Int = 0 //但它的属性和函数都是 private,只能在 Dog结构声明里使用。
    func run() {} //跟随 Dog的等级,都是fileprivate 
}
fileprivate struct Person {
    var dog: Dog = Dog()
    mutating func walk() {
        dog.run() //可以访问
        dog.age = 1 //❌编译报错,因为age 是private的
    }
}
  • 准则5: 可以单独设定属性的 set 和 get的访问等级
struct Dog {
    fileprivate private(set) var age: Int = 0 //get是 fileprivate,set 是 private
}
  • 准则6: 不能给枚举的值单独设置访问等级
enum Weather {
	case winter
	private case spring //❌
}