Reputation: 4378
I have an NSObject subclass, BaseClass
. BaseClass is a placeholder class for a couple subclasses, SubClassA
and SubClassB
. There is an instance variable that I have present on both of the subclasses. They're the same name, and are both of a corresponding subclass of another object. They're often used in very similar ways, so I wanted to move some functionality from my SubClassA and SubClassB to the BaseClass. However, I need access to that variable.
If I move the variable into the BaseClass
, I am unable to specify the proper subclass of it in SubClassA
and SubClassB
, saying I can't override it. If I use the common parent class of this instance variable in the BaseClass
, I lose some access to things that aren't common between how SubClassA
and SubClassB
work.
This is a more primitive example, but the basics of what I'm trying to do. This example obviously does not work. Are my only options to choose having to define common functionality within SubClassA
and SubClassB
or is there a proper way to achieve my goal here?
class BaseClass: NSObject {
var myObject: MyObject
}
class SubClassA: BaseClass {
override var myObject: MyObjectA
}
class SubClassB: BaseClass {
override var myObject: MyObjectB
}
class MyObject: NSObject { }
class MyObjectA: MyObject { }
class MyObjectB: MyObject { }
This gives me the error:
Property 'myObject' with type 'MyObjectA' cannot override a property with type 'MyObject'
Upvotes: 3
Views: 68
Reputation: 2329
You can create a class function in your BaseClass
that returns a class that inherits from a BaseObject
(myObject) and override it for whichever class you need.
class BaseClassObject: NSObject {
}
class BaseClass: NSObject {
func generateClass() -> NSObject {
return BaseClassObject()
}
}
class BranchedObject: BaseClassObject {
}
class SubClassA: BaseClass {
var myObject: NSObject?
override func generateClass() -> NSObject {
return BranchedObject()
}
override init() {
super.init()
self.myObject = self.generateClass()
}
}
Upvotes: 0
Reputation: 22689
Instead of putting the myObject
related code into BaseClass
, you could put it into a protocol extension. Consider this:
class BaseClass {
}
class SubClassA: BaseClass, HasMyObject {
var myObject: MyObjectA
}
class SubClassB: BaseClass {
var myObject: MyObjectB
}
class MyObject { }
class MyObjectA: MyObject { }
class MyObjectB: MyObject { }
protocol HasMyObject {
associatedtype MyObjectClass
var myObject: MyObjectClass { get set }
}
This is conceptually very similar to using generics, but would separate your myObject
related code from the rest of the code in your class. Whether this is actually preferable over generics depends on your coding style and specific use-cases.
Upvotes: 2
Reputation: 2477
How about using generic? For simplicity, I removed NSObject
class MyObject {
}
class MyObjectA: MyObject {
}
class MyObjectB: MyObject {
}
class BaseClass<T> where T : MyObject {
var myObject: T?
}
class SubClassA: BaseClass<MyObjectA> {
}
class SubClassB: BaseClass<MyObjectB> {
}
Upvotes: 4