我根据 this answer 使用协议(protocol)扩展在 Swift 中创建了一个类似于抽象基类的结构.这是一个简化的例子:
protocol AbstractBase {
var _constant: Int { get }
func _operation(_ val: Int) -> Int
}
public class ConcreteSub: AbstractBase {
let _constant: Int = 42
func _operation(_ val: Int) -> Int {
return val + 2
}
}
extension AbstractBase {
func mainOperation(_ val: Int) -> Int {
return _operation(val + _constant)
}
}
所以基本上,ConcreteSub
提供 AbstractBase
所需的实现细节, 即 _constant
和 _operation
.
我想对客户隐藏这些细节,只公开 mainOperation
.但是,如果我执行以下操作,Swift 不允许我将成员设为私有(private)文件
protocol AbstractBase {
fileprivate var _constant: Int { get }
// etc
我收到“错误:‘fileprivate’修饰符不能在协议(protocol)中使用”。
我也不能在子类上应用修饰符——当我尝试时
public class ConcreteSub: AbstractBase {
fileprivate let _constant: Int = 42
// etc
我收到“错误:属性‘_constant’必须声明为内部,因为它符合内部协议(protocol)‘AbstractBase’中的要求”。
最后,当我将整个协议(protocol)文件设为私有(private)时,我没有遇到编译错误,但我一直遇到链接错误,我猜这是因为协议(protocol)是私有(private)的,但子类是公共(public)的。
还有其他方法我想念吗?
最佳答案
当我需要一个隐藏了一些属性/函数的抽象基础时,我使用带有一些额外的 fatalErrors
和 asserts
的类,以便在有人试图使用 Base 而不是实现时崩溃.
public class AbstractBase {
init() {
assert(type(of: self) != AbstractBase.self, "Abstract class")
}
fileprivate var _constant: Int {
fatalError("Abstract class")
}
fileprivate func _operation(_ val: Int) -> Int {
fatalError("Abstract class")
}
func mainOperation(_ val: Int) -> Int {
return _operation(val + _constant)
}
}
public class ConcreteSub: AbstractBase {
fileprivate override var _constant: Int {
return 42
}
fileprivate override func _operation(_ val: Int) -> Int {
return val + 2
}
}
关于Swift:具有私有(private)成员的抽象基类/协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43887462/