我偶然发现了一个问题,无法弄清楚该如何解决。
假设我们有一个基类(可能来自FrameworkA),其属性名为subject
:
public class MyClass {
public var subject: String
}
我们有一个协议(protocol)(可能来自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%...
最佳答案
好的,让我们从使用这些类的代码的 Angular 来看一下问题,而忽略它们的实现方式。
事实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
属性可消除任何混淆风险。希望这可以帮助。