我下面所说的成员,是指的范例的成员变量和成员函数.
一.概述
Swift的权限控制在英语中称为Privacy,又可以叫access control
共有五种:
- internal
默认权限.
在模块内的文件,其类界说和函数界说是相互可见的,但是模块外是不可见的,以是它又可明确为:对模块私有.
这一点和C,Objective-C差别,在C和Objective-C内里,纵然在模块内部,假如没有使用include大概import语句,文件间的对象就彼此不可见.
- fileprivate(比internal权限更小)
只在文件内可见.即:2个界说在同一个文件中的范例相互之间可见,但是其他文件就不可见这两个范例.
- private(比fileprivate权限更小)
一个声明为private的东东只在界说它的花括号内可见.比如一个范例的private成员变量只在这个范例的声明中可见
但是:一个写在文件顶层的private的声明,它着实是fileprivate的,这个很好明确哈
- public(比internal权限更大)
在模块外可见.想要如许也不是光声明确public就可以,它须要满意2个条件:
- 另一个模块B必须import这个模块A,
- 模块A想要B可见的内容,如类,类的成员,必须声明为public
如许模块B才可以看到模块A中被声明为public的东西
假如自己实现了一个模块,比如package或则framework,你必须至少把此中的一个范例标记为public,否则别的模块就算import了你的module,也无法看到任何范例.
- open(比public权限更大)
假如一个模块中的类声明为open,则另一个模块可以子类化这个模块的类,可以重写它的成员
二. 详解
Private 和 Filepivate
- 假如父类的成员声明为private,则子类不能看到父类的private的成员.
假如子范例想要看到父范例的private成员,可以这么做:
- 把父范例的成员为声明从private改成fileprivate
- 把子范例和父范例写在同一个文件中
- 一个类内嵌的范例可以看到该类全部的私有成员
- extension可以看到它所扩展的范例的全部私有成员,条件是范例的extension和范例声明写在同一个文件中
例:
class Dog { private var whatADogSays = "woof"} extension Dog { func speak() { print(self.whatADogSays) // ok }}
- 一个变量的set和get可以有差别的访问权限
如:
private(set) var myVar意味着该变量的set是private的,但是get还是internal的
public private(set) var myVar 意味着该变量的get是public的,set是private的
- Objective-C 增长了权限访问的复杂度:
- 被标记为@objc的东东是private,但是Objective-C依然可以望见它们.这种环境也包罗了被标记为@IBAction和@IBOutlet的对象,由于它们着实是隐式的@objc
- 假如实现了一个Objective-C 的protocol, 那些属于protocol的成员不能被标记成private,
- 而且,在Cocoa界说的protocol中界说的可选实现的方法(optional method)必须至少实现为internal,否则Cocoa找不到也无法调用它们.
Public 和 Open
- public界说了模块中的公有API.一个framework就是一个模块.
- 假如一个公用范例的初始化函数是隐式的,则其他模块并不能创建这个范例的对象,该初始化函数必须被表现声明并标记为public
- 一个public修饰的类.在另一个模块中,这个类只是可见,不能被继续;而open修饰的类可以被继续.
- 一个open修饰的类假如有个public修饰的成员,在另一个模块中,这个成员不能被重写;只有open修饰的成员可以被重写.
|