swift – 协议之间的实现冲突

我偶然发现了一个问题,我无法弄清楚如何解决它.

假设我们有一个基类(可能来自FrameworkA),其属性名为subject:

public class MyClass {
    public var subject: String
}

我们有一个协议(可能来自FrameworkB),另一个属性但具有相同的名称

public protocol MyProtocol {
    var subject: String { get }
}

这两个属性代表完全不同的东西.

如何创建一个继承自MyClass并实现MyProtocol的类?
我该如何使用这些属性

public class SecondClass: MyClass,MyProtocol {
    var MyProcotol.name: String { // <==== ObvIoUsly not allowed
        return "something"
    }
    var MyClass.name: String { // <==== ObvIoUsly not allowed
        return "something else"
    }
}

我认为C#允许这样的声明,但我不是100%肯定…

好吧,暂时让我们从使用这些类的代码的角度来看问题,让我们忽略它们的实现方式.

事实1

如果secondClass:SecondClass扩展了MyClass,那么我希望能够写:

secondClass.subject

事实2

如果secondClass符合MyProtocol,那么我希望能够写

secondClass.subject

如果我们为secondClass创建一个不同的方式来公开MyClass.subject和MyProtocol.subject,那么我们就打破了面向对象的范式.

事实上

>当你扩展一个类时,你隐式地继承了所有非私有属性方法,你不能(并且这是一件好事)重命名它们.
>当您遵循协议时,您将完全按照协议中的描述公开所有非可选的声明属性方法

如果SecondClass重命名了2个属性,就像你的伪代码一样,我们将无法编写类似这样的东西.

let list : [MyClass] = [MyClass(),SecondClass()]

for elm in list {
    println(elm.subject)
}

一种可能的(部分)解决方

你应该避免使用is-a方法支持has-a.

class SecondClass {
    let myClass : MyClass
    let somethingElse : MyProtocol

    init(myClass : MyClass,somethingElse:MyProtocol) {
        self.myClass = myClass
        self.somethingElse = somethingElse
    }

    var myClassSubject : String { get { return myClass.subject } }
    var myProtocolSubject : String { get { return somethingElse.subject } }
}

从那以后

> SecondClass不是MyClass和
> SecondClass不是MyProtocol

它没有主题属性消除任何混淆的风险.

希望这可以帮助.

相关文章

Swift 正式开源!Swift 团队很高兴宣布 Swift 开始开源新篇章。自从苹果发布 Swfit 编程语言,就成为了...
快,快,快!动动您的小手,分享给更多朋友! 苹果去年推出了全新的编程语言Swift,试图让iOS开发更简单...
开发者(KaiFaX) 面向开发者、程序员的专业平台! 和今年年初承诺的一样,苹果贴出了Swift语言的源码,...
本文由@Chun发表于Chun Tips :http://chun.tips/blog/2014/12/11/shi-yong-swift-gou-jian-zi-ding-yi...
本文由CocoaChina译者leon(社区ID)翻译 原文:THE RIGHT WAY TO WRITE A SINGLETON 在之前的帖子里聊过...
本文由CocoaChina译者leon(社区ID)翻译 原文:THE RIGHT WAY TO WRITE A SINGLETON 在之前的帖子里聊过...