Swift中的'open'关键字是什么?


334

ObjectiveC.swift来自标准库的文件包含围绕第228行的以下几行代码:

extension NSObject : Equatable, Hashable {
  /// ...
  open var hashValue: Int {
    return hash
  }
}

open var在这种情况下是什么意思,或者open通常是什么关键字?


2
可能相关:stackoverflow.com/questions/24003918/…(“ open和之间有什么区别public?”)
Ahmad F

旁注:关键字“开放”来自“开放扩展,关闭进行修改”的概念
Sazzad Hissain Khan,

Answers:


572

open 是Swift 3中的新访问级别,随实现而引入

自2016年8月7日起,Swift 3快照和Xcode 8 beta 6都可以使用它。

简而言之:

  • open类是可访问的,并可以子类的定义模块之外。一open类成员是可访问可重写的定义模块的外部。
  • public类是可访问的,但不是子类化的定义模块之外。甲public类成员是可访问的,但 不可重写的定义模块的外部。

那么open是什么public曾经在以前的版本雨燕和的访问public受到限制。或者,如Chris Lattner在 SE-0177中所述:允许区分公共访问权限和公共可重写性

现在,“开放”只是“比公众更公开”,提供了一个非常简单和干净的模型。

在您的示例中,open var hashValue是一个可以访问的属性,可以在NSObject子类中覆盖它。

有关更多示例和详细信息,请查看SE-0117


16
所以public在Swift 3中就像public final在Swift 2中一样,open就像public吗?
Clashsoft '16

16
@Clashsoft:Swift 3中的“ open”就像Swift 2中的“ public”一样。Swift3中的“ public”在Swift 2中没有等效项。(即使在同一模块中,也不能对最终类进行子类化。)
Martin R

59
这是荒谬的直觉。感谢您的总结。
GoldenJoe

7
同意@MikeS,由于缺乏向后兼容性,这使情况变得很糟。
HughHughTeotl '16

14
@MikeS苹果-认为有所不同,即使不必要。
Varun Nath

12

阅读为

在其他模块中开放继承

我在其他模块中重复开放继承。因此,打开了一个开放类,以便在其他包含定义模块的模块中进行子类化。开放变量和函数开放以在其他模块中覆盖。它是限制性最小的访问级别。就像公共访问接受那样,公共的内容对于其他模块中的继承是封闭的,这是很好的。

Apple Docs

开放式访问仅适用于班级和班级成员,它与公共访问有所不同,如下所示:

  1. 具有公共访问权限或更高级别的访问权限的类只能在定义它们的模块内被子类化。

  2. 具有公共访问权限或任何更高访问权限级别的类成员只能在定义它们的模块内被子类覆盖。

  3. 开放类可以在定义它们的模块内以及在导入定义它们的模块的任何模块内子类化。

  4. 开放类成员可以由定义它们的模块内的子类以及导入定义它们的模块的任何模块内的子类覆盖。

5

开放是一种访问级别,是为了对Swift的类继承施加限制而引入的。

这意味着开放访问级别只能应用于类和类成员

在课堂上

开放类可以在其定义的模块中以及在导入定义该类的模块的模块中子类化。

班级成员

同样适用于班级成员。打开的方法可以在定义该模块的模块中以及导入该方法的模块中的模块中的子类覆盖。

此更新的需要

某些类的库和框架并非设计为子类化,这样做可能会导致意外行为。Apple原生库也不允许覆盖相同的方法和类,

因此,添加之后,它们将相应地应用公共和私有访问级别。

有关更多详细信息,请参阅访问控制上的Apple文档。


1

除子类外,open class func还可以从项目中的任何位置访问an 。假设您正在像这样在Util类中定义一个开放类函数

open class Utils: NSObject {
    open class func printHello() {
        print("Hello from utils")
    }
}

然后,在您的任何视图控制器中,只需调用以下内容即可访问此方法

Utils.printHello()

3
这个答案并没有说明它与公开的区别,因为您也可以通过公开来做到这一点。
何塞·拉米雷斯

需要更多有关它的解释
MD Aslam Ansari


0

open仅用于另一个模块,例如:可可豆荚或单元测试,我们可以继承或覆盖

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.