Here's an example of a good old fashion single inheritance OO class tree:
class Common {
var foo:String = ""
var bar:Int = 0
// common behavior to deal with foo + bar
}
class SubA:Common {
var yak:Double = 0.0
// specialized behavior to deal with yak, foo, and bar
}
class SubB:Common {
var baz:CGFloat = 1.0
// specialized behavior to deal with baz, foo, and bar
}
Pretty straightforward. Swift gives us lots of new ways to think about things, but this is still a very common OO paradigm and often worthwhile to use. If I want to create ViewControllers that interact with these, it's tempting to follow the same pattern:
class CommonViewController:UIViewController {
var model:Common!
// common behavior to deal with the common behavior found in the Common superclass
}
class SubAViewController:CommonViewController {
var model:SubA!
// more methods to deal with the specializations that SubA provides
}
class SubBViewController:CommonViewController {
var model:SubB!
// more methods to deal with the specializations that SubA provides
}
Again, pretty standard construct. Unfortunately, Swift's type system will not allow it:
error: cannot override mutable property 'model' of type 'Common!' with covariant type 'SubA!'
var model:SubA!
Is there an easy to solve this? The simplest I could think of is to do the sub ViewControllers as:
class SubAViewController:CommonViewController {
var subA:SubA {
get {
return self.model as! SubA
}
set {
self.model = newValue
}
}
// some behavior will need to use self.subA to get that type of data
}
class SubBViewController:CommonViewController {
var subB:SubB {
get {
return self.model as! SubB
}
set {
self.model = newValue
}
}
// some behavior will need to use self.subA to get that type of data
}
This adds 2 had-to-do-this-to-make-it-work methods and the constraint that some of my subclass methods will have to refer to self.subB
or self.subA
rather than self.model
. I started working through how to do this with protocols and extensions, but I just felt like I was adding more and more hoops to make the solution be what I wanted. Is there a simpler solution that one can use with Swift to implement this very classic and common OO inheritance pattern?