我偶然发现了一个问题,我无法弄清楚如何解决它。
假设我们有一个基类(可能来自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%确定...
答案 0 :(得分:3)
如果您可以控制此基类和/或协议,则可以为属性指定唯一名称并解决问题。
如果你不能这样做,问题就在于SecondClass
是否真的必须履行这两个相互冲突的责任。具体来说,MyProtocol
是什么?一些代表协议?您可以让SecondClass
出售符合该协议的单独对象,从而消除冲突的双重角色。
底线,而不是让单个对象尝试服务于两个相互冲突的目的,将责任分成单独的对象来解决任何此类冲突。
答案 1 :(得分:1)
好的,暂时让我们从使用这些类的代码的角度来看问题,让我们忽略它们的实现方式。
如果 secondClass :SecondClass扩展MyClass
,那么我希望能够写:
secondClass.subject
如果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
subject
属性没有消除任何混淆的风险。
希望这会有所帮助。