我已经使用协议扩展在swift中创建了一个抽象的类结构,如this answer所示。这是一个简单的例子:

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不允许我在协议中对成员进行私有化——如果我执行以下操作
protocol AbstractBase {
    fileprivate var _constant: Int { get }
    // etc

我得到“错误:fileprivate”修饰符不能在协议中使用。
我也不能在子类上应用修饰符——当我尝试
public class ConcreteSub: AbstractBase {
    fileprivate let _constant: Int = 42
    // etc

我得到“error:property'\u constant'必须声明为internal,因为它符合内部协议'abstractbase'中的要求。”
最后,当我将整个协议文件设为私有时,我没有得到编译错误,但是我总是遇到链接错误,我猜这是因为协议是私有的,但是子类是公共的。
有没有别的方法让我失踪?

最佳答案

当我需要一个隐藏了一些属性/函数的抽象基时,我使用带有一些额外的fatalErrorsasserts的类来崩溃,每当有人试图使用基而不是实现时。

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 - Swift:具有私有(private)成员的抽象基类/协议(protocol),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43887462/

10-15 15:06