Swift 中的“open”关键字是啥?
Posted
技术标签:
【中文标题】Swift 中的“open”关键字是啥?【英文标题】:What is the 'open' keyword in Swift?Swift 中的“open”关键字是什么? 【发布时间】:2016-12-21 04:30:23 【问题描述】:标准库中的ObjectiveC.swift
文件在第 228 行附近包含以下几行代码:
extension NSObject : Equatable, Hashable
/// ...
open var hashValue: Int
return hash
open var
在这种情况下是什么意思,或者一般来说open
关键字是什么?
【问题讨论】:
可能相关:***.com/questions/24003918/…(“open
和public
有什么区别?”)
旁注:关键字“open”来自“对扩展开放,对修改关闭”的概念
【参考方案1】:
open
是 Swift 3 中的新访问级别,在实现中引入
的
从 2016 年 8 月 7 日起,它与 Swift 3 快照一起提供, 以及 Xcode 8 beta 6。
简而言之:
open
类在
定义模块。 open
类成员可访问,并且
在定义模块之外可覆盖。
public
类在
定义模块。 public
类成员可访问,但
在定义模块之外不可覆盖。
所以open
是以前的public
Swift 发布,public
的访问受到限制。
或者,正如 Chris Lattner 所说
SE-0177: Allow distinguishing between public access and public overridability:
“开放”现在只是“比公共更公开”,提供了一个非常简单和干净的模型。
在您的示例中,open var hashValue
是一个可访问的属性,并且可以在 NSObject
子类中被覆盖。
有关更多示例和详细信息,请查看SE-0117。
【讨论】:
所以 Swift 3 中的public
就像 Swift 2 中的 public final
,而 open
就像 public
?
@***soft: Swift 3 中的“open”就像 Swift 2 中的“public”。Swift 3 中的“public”在 Swift 2 中没有等价物。(最终类根本不能子类化,不是即使在同一个模块中。)
这非常违反直觉。感谢您的总结。
同意@MikeS,缺乏向后兼容性让这变得一团糟。
@MikeS apple - 想不同,即使没有必要。【参考方案2】:
阅读打开方式
在其他模块中打开继承
我在其他模块中重复打开继承。 因此,一个开放类对于包含定义模块的其他模块中的子类化是开放的。开放的变量和函数是开放的,可以在其他模块中覆盖。它是限制最少的访问级别。它和公共访问一样好,只是公共的东西被关闭以便在其他模块中继承。
来自Apple Docs:
开放访问仅适用于类和类成员,它与公共访问的区别如下:
具有公共访问权限或任何更多限制访问级别的类可以 只能在定义它们的模块内进行子类化。
具有公共访问权限或任何更严格访问级别的班级成员可以 仅在它们所在的模块内被子类覆盖 已定义。
开放类可以在定义它们的模块中进行子类化,也可以在导入该模块的任何模块中进行子类化 它们被定义了。
开放类成员可以被子类覆盖 在定义它们的模块中,以及在任何模块中 导入定义它们的模块。
【讨论】:
【参考方案3】:Open 是一个访问级别,被引入是为了对 Swift 的类继承施加限制。
这意味着开放访问级别只能应用于类和类成员。
在课堂上
一个开放的类可以在它定义的模块和导入该类定义的模块的模块中进行子类化。
班级成员
这同样适用于班级成员。 open 方法可以被定义它的模块中的子类以及导入定义该方法的模块的模块中的子类覆盖。
本次更新的必要性
某些类的库和框架并未设计为子类化,这样做可能会导致意外行为。原生 Apple 库也不允许覆盖相同的方法和类,
因此,在此添加之后,他们将相应地应用公共和私人访问级别。
更多详情请看Apple Documentation on Access Control
【讨论】:
【参考方案4】:open 在处理多个模块的时候来玩。
open 类可以在定义模块之外访问和子类化。一个开放的类成员可以在定义模块之外访问和覆盖。
【讨论】:
【参考方案5】:open 只针对另一个模块,例如:cocoa pods,或者单元测试,我们可以继承或者覆盖
【讨论】:
以上是关于Swift 中的“open”关键字是啥?的主要内容,如果未能解决你的问题,请参考以下文章