考虑模块中的以下类(同样适用于结构):
public class Foo {
public func bar() {
// method body
}
}
注意,它没有显式的初始化器;这个示例不需要任何特殊的初始化。此类将向其他模块公开,因为它被标记为public
。但是,当模块外部的代码试图初始化它时,编译器会报错:
let foo = Foo() // 'Foo' initializer is inaccessible due to 'internal' protection level
为了满足编译器的要求,我必须定义一个显式的空初始化器,标记为public
public class Foo {
public init() {
// This initializer intentionally left empty
}
public func bar() {
// do something useful
}
}
为什么,如果类显式定义了public
**,,我需要显式定义一个公共初始值设定项(public
**,)?它不应该隐式有一个公共初始值设定项吗?**
有一个相关的问题here,与单元测试有关,但我发现它并没有真正进入设计哲学的核心,我发现这是一个令人惊讶的问题。
发布于 2016-10-26 06:55:58
将类标记为public并不一定意味着开发人员希望该类被公开初始化。例如,我经常编写基类,这些基类只为我自己而存在,以便能够对它们进行子类化。我为这些超类提供了internal
初始化器,以便它们的子类可以访问它们,但外部世界中的那些不应该直接使用它们。例如,Foundation
中的Operation
没有可访问的初始值设定项,但该类是公共的。它只是意味着要被子类化。这在Objective-C中被认为是一个抽象类。
由于Swift不包含对抽象类的显式支持,因此将类设为公共但没有公共初始值设定项的行为基本上用作抽象类(除非每个函数仍必须有默认定义,无论是在类本身中还是在某个协议扩展中)。
考虑到这一点,下面是一些Swift规则:
private
,则所有变量、初始化和函数都将默认为internal
您的类被标记为internal
(默认)、public
或open
,所有变量、初始化和函数将默认为Swift子类的超类必须至少为accessible.public
的类成员将作为open
导入到Swift中,因为在Objective-C中没有这样的区别第二个就是你要碰到的那个。默认的初始化是选择默认的internal
,因为Swift最不想做的事情就是将你的初始化公开为public API,除非它被明确指示这样做。
注意:在我的测试中(至少在游乐场上),似乎随着fileprivate
的引入
private
或fileprivate
,则除非显式注释了fileprivate
https://stackoverflow.com/questions/40249531
复制相似问题