I've stumbled upon an issue, and I can not figure out how am I going to solve it.
Let's suppose we have a base class (that may comes from FrameworkA), with a property named subject
:
public class MyClass {
public var subject: String
}
And we have a protocol (that may comes from FrameworkB), with another property but with the same name:
public protocol MyProtocol {
var subject: String { get }
}
Those two properties represent totally different things.
How can I create a class that inherits from MyClass
and implements MyProtocol
?
And how can I use these properties?
public class SecondClass: MyClass, MyProtocol {
var MyProcotol.name: String { // <==== Obviously not allowed
return "something"
}
var MyClass.name: String { // <==== Obviously not allowed
return "something else"
}
}
I think that C# allows some kind of declaration like this, but I'm not 100% sure...
If you have control over this base class and/or the protocol, you can give the properties unique names and that solves the problem.
If you cannot do that, the question becomes whether SecondClass
really has to fulfill these two conflicting responsibilities itself. Specifically, what is MyProtocol
? Some delegate protocol? You could instead have SecondClass
vend a separate object that conforms to that protocol, eliminating the conflicting dual roles.
Bottom line, rather than having a single object attempt serve two conflicting purposes, split the responsibilities into separate objects resolving any such conflict.
Ok, for a moment let's look at the problem from the point of view of the code that does use these classes and let's ignore how they are implemented.
If secondClass : SecondClass extends MyClass
then I expect to be able to write:
secondClass.subject
If secondClass
conforms to MyProtocol
then I expect to be able to write
secondClass.subject
If we create a different way for secondClass
to expose MyClass.subject
and MyProtocol.subject
we are breaking the Object Oriented Paradigm.
If SecondClass
renamed the 2 properties like in your pseudo-code, we would not be able to write something like this.
let list : [MyClass] = [MyClass(), SecondClass()]
for elm in list {
println(elm.subject)
}
You should avoid the is-a approach in favor of the 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 } }
}
Now since
SecondClass
is not a MyClass
andSecondClass
is not a MyProtocol
It has not the subject
property removing any risk of confusion.
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With