【发布时间】:2015-03-12 22:28:20
【问题描述】:
我试图在 swift 中声明一个实例属性,以便它只对其类和子类可见。我相信这将在其他语言中被称为受保护的财产。有没有办法在 Swift 中实现这一点?
【问题讨论】:
标签: swift access-control
我试图在 swift 中声明一个实例属性,以便它只对其类和子类可见。我相信这将在其他语言中被称为受保护的财产。有没有办法在 Swift 中实现这一点?
【问题讨论】:
标签: swift access-control
沿继承线的访问控制并不真正符合 Swift 和 Cocoa 背后的设计理念:
在 Swift 中设计访问控制级别时,我们考虑了两个主要用例:
- 保持
private类的详细信息对应用程序的其余部分隐藏- 保持
internal对客户端应用隐藏的框架详细信息这些分别对应于
private和internal的访问级别。相比之下,
protected将访问与继承混为一谈,添加了一个全新的控制轴来进行推理。它实际上并没有提供任何真正的保护,因为子类总是可以通过新的公共方法或属性公开“受保护”的 API。它也不提供额外的优化机会,因为新的覆盖可以来自任何地方。而且它是不必要的限制——它允许子类访问某些东西,但不允许子类的任何助手访问。
还有进一步的解释on Apple's Swift blog。
【讨论】:
protected 不是很有保护性的部分,以及辅助类...... Cocoa 比其他语言使用的库更具动态性,并且也倾向于支持不同的设计模式(比如组合优于继承),因此适用于其他工具包的解决方案可能不属于为 Cocoa 设计的语言。
fileprivate - 在文件范围内隐藏详细信息。虽然它同样保留了访问/继承的区别,但在审查您的选项时,它是另一个有用的范围级别。
一种方法是使用 fileprivate 关键字定义函数或属性,并在同一个文件中定义子类,如下所示:
class Parent {
fileprivate var someProperty: Any?
}
class Child: Parent {
func someFunction() {
print(someProperty)
}
}
当然这很烦人,因为那个文件会很乱。更不用说为什么 Swift 允许这样做,但 protected 不允许这样做只是......啊。
【讨论】: