在swift 3中新增长了两种访问控制权限 fileprivate
和 open
。swift
下面结合网上资料和我的理解整理一下两个属性的原理与介绍。markdown
在原有的swift中的 private
其实并非真正的私有,若是一个变量定义为private,在同一个文件中的其余类依然是能够访问到的。这个场景在使用extension的时候很明显。框架
class User {
private var name = "private"
}
extension User{
var accessPrivate: String {
return name
}
}
复制代码
这样带来了两个问题:ide
由此,在swift 3中,新增长了一个 fileprivate
来显式的代表,这个元素的访问权限为文件内私有。spa
过去的private对应如今的fileprivate。如今的private则是真正的私有,离开了这个类或者结构体的做用域外面就没法访问。设计
因此fileprivate > private .code
open则是弥补public语义上的不足。 如今的pubic有两层含义:orm
继承是一件危险的事情。尤为对于一个framework或者module的设计者而言。在自身的module内,类或者属性对于做者而言是清晰的,可否被继承或者override都是可控的。可是对于使用它的人,做者有时会但愿传达出这个类或者属性不该该被继承或者修改。这个对应的就是 final
。继承
final
的问题在于在标记以后,在任何地方都不能override。而对于lib的设计者而言,但愿获得的是在module内能够被override,在被import到其余地方后其余用户使用的时候不能被override。作用域
这就是 open
产生的初衷。经过open和public标记区别一个元素在其余module中是只能被访问仍是能够被override。
通俗的理解public和open就是:
public:能够被任何人访问,但其余module中不能够被override和继承,而在本module内能够被override和继承。 open:能够被任何人使用,包括override和继承。
下面是例子:
/// ModuleA:
// 这个类在ModuleA的范围外是不能被继承的,只能被访问
public class NonSubclassableParentClass {
public func foo() {}
// 这是错误的写法,由于class已经不能被继承,
// 因此他的方法的访问权限不能大于类的访问权限
open func bar() {}
// final的含义保持不变
public final func baz() {}
}
// 在ModuleA的范围外能够被继承
open class SubclassableParentClass {
// 这个属性在ModuleA的范围外不能被override
public var size : Int
// 这个方法在ModuleA的范围外不能被override
public func foo() {}
// 这个方法在任何地方均可以被override
open func bar() {}
///final的含义保持不变
public final func baz() {}
}
/// final的含义保持不变
public final class FinalClass { }
复制代码
/// ModuleB:
import ModuleA
// 这个写法是错误的,编译会失败
// 由于NonSubclassableParentClass类访问权限标记的是public,只能被访问不能被继承
class SubclassA : NonSubclassableParentClass { }
// 这样写法能够经过,由于SubclassableParentClass访问权限为 `open`.
class SubclassB : SubclassableParentClass {
// 这样写也会编译失败
// 由于这个方法在SubclassableParentClass 中的权限为public,不是`open'.
override func foo() { }
// 这个方法由于在SubclassableParentClass中标记为open,因此能够这样写
// 这里不须要再声明为open,由于这个类是internal的
override func bar() { }
}
open class SubclassC : SubclassableParentClass {
// 这种写法会编译失败,由于这个类已经标记为open
// 这个方法override是一个open的方法,则也须要代表访问权限
override func bar() { }
}
open class SubclassD : SubclassableParentClass {
// 正确的写法,方法也须要标记为open
open override func bar() { }
}
open class SubclassE : SubclassableParentClass {
// 也能够显式的指出这个方法不能在被override
public final override func bar() { }
}
复制代码
如今的访问权限 由大到小 依次为:open,public,internal(默认),fileprivate,private。
此外,internal是系统默认访问级别,internal修饰符可写可不写。
internal访问级别所修饰的属性或方法在源代码所在的整个模块均可以访问。
若是是框架或者库代码,则在整个框架内部均可以访问,框架由外部代码所引用时,则不能够访问。
若是是App代码,也是在整个App代码,也是在整个App内部能够访问。