swift - 如何使用 Swift 协议(protocol)扩展来创建可以修改私有(private)属性的共享代码?

标签 swift inheritance protocols

假设场景:

有类:ClassA;和 ClassB。两者都实现了 ProtocolC,其中包含单一要求 func createKey()ProtocolC 有一个 extension 实现了 createKey() 因为关于这个函数,ClassAClassB 是相同的。但是,createKey() 的实现需要访问 ClassAClassB 都包含的名为 uniqueKey 的私有(private)变量,其值在两个类中需要不同(如您所想)。 ProtocolCcreateKey()extension 因此变得无用 - 因为变量是 fileprivate - 这意味着它的代码有在 ClassAClassB 中复制。但重复代码是编程禁忌。一个解决方案可能是使用父类(super class)而不是协议(protocol)扩展,但这与 Swift 试图实现的目标背道而驰。继承是 Swift 的禁忌。

// the ideal:

class ClassA: ProtocolC {
    fileprivate var uniqueKey: String?
}

class ClassB: ProtocolC {
    fileprivate var uniqueKey: String?
}

protocol ProtocolC {
    func createKey()
}

extension ProtocolC {
    func createKey(){
        uniqueKey = NSUUID().uuidString
    }
}



// the reality:

class ClassA: ProtocolC {
    fileprivate var uniqueKey: String?
    func createKey(){
        uniqueKey = NSUUID().uuidString
    }
}

class ClassB: ProtocolC {
    fileprivate var uniqueKey: String?
    func createKey(){
        uniqueKey = NSUUID().uuidString
    }
}

uniqueKey 需要锁定在两个类中,不可设置也不可从外部获取。 Swift 中写什么解决方案:可以访问私有(private)属性的泛型代码;同时避免继承?

感谢阅读。

最佳答案

这里有一些非常接近您的理想。缺点是在扩展方法中转换了运行时协议(protocol),但它实现了您正在寻找的访问控制级别(fileprivate 存储的 var)和通过协议(protocol)扩展的代码重用:

fileprivate protocol UniqueKeyDefining {
    var uniqueKey: String? { get set }
}

class ClassA: ProtocolC, UniqueKeyDefining {
    fileprivate var uniqueKey: String?
}

class ClassB: ProtocolC, UniqueKeyDefining {
    fileprivate var uniqueKey: String?
}

protocol ProtocolC {
    func createKey()
}

extension ProtocolC {
    func createKey(){
        if var hasUniqueKey = self as? UniqueKeyDefining {
            hasUniqueKey.uniqueKey = NSUUID().uuidString
        } else {
            // Some default behavior if the conformer to ProtocolC isn't also UniqueKeyDefining
        }
    }
}

协议(protocol) UniqueKeyDefining 在声明它的文件之外是不可见的,具有 ClassAClassB,所以没有代码在文件知道那些类符合它或者可以看到它们的 uniqueKey ivars。

ProtocolC 的特定协议(protocol)扩展在同一文件中声明,因此它确实知道UniqueKeyDefining 并且可以有条件地转换 self 在运行时访问该协议(protocol),以通过该 fileprivate 协议(protocol)访问 uniqueKey ivar。

它似乎不是非常可扩展或可重用此文件之外的类,但它满足我从你的问题中解释的一组狭窄的要求。

关于swift - 如何使用 Swift 协议(protocol)扩展来创建可以修改私有(private)属性的共享代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47563874/

相关文章:

ios - MKMapPoint 到 CGPoint

ios - Swift ios 如何设置导航栏图像不拉伸(stretch)

swift - SceneKit—— fatal error : unexpectedly found nil while unwrapping an Optional value when getting child node

arrays - 在 Swift 函数中引用数组

css - 两个连续调用的样式表中的第二个能否覆盖第一个中定义的所有样式?

Python Twisted 协议(protocol)取消注册?

javascript - 在基于 REST 的 Web 应用程序中保留继承的概念

c++ - 继承实际上会导致类的成员为 'inherited' 吗?

security - 一个简单的、中等安全的登录协议(protocol)?

swift - Swift 中所有数字都遵循哪些协议(protocol)?