Say I have BaseClass
, DerivedClassOne
, DerivedClassTwo
, a magical factory method giveMeAnObjectOfType(type: String) -> BaseClass
, and the following code
func myBeautifulFunction(index: Int) -> BaseClass {
let type : String = self.someArray[index]
var anObject : BaseClass
switch type {
case "TypeOne":
// This won't work
anObject = self.giveMeAnObjectOfType("DerivedClassOne") as! DerivedClassOne
anObject.methodOfDCOne()
case "TypeTwo":
// Neither will this
anObject = self.giveMeAnObjectOfType("DerivedClassTwo") as! DerivedClassTwo
anObject.methodOfDCTwo()
default:
// Throw a tantrum here
}
return anObject
}
This will result in errors saying that anObject does not contain either methodOfDCOne()
or methodOfDCTwo()
. Question: how do I cast my objects properly?
Basically, I could achieve the same by having several return statements within the switch's cases, but I don't like how that looks. Besides, if I wanted to call some methods of BaseClass
, I'd have tons of repeated code.
anObject.methodOfDCOne()
does not compile because methodOfDCOne
is not an instance method
of BaseClass
(or its superclasses).
You have to create objects of the subclass type first so that you can call the subclass methods. Then assign (upcast) the object to the base class variable:
func myBeautifulFunction(index: Int) -> BaseClass {
let type : String = self.someArray[index]
let anObject : BaseClass
switch type {
case "TypeOne":
let dc1 = self.giveMeAnObjectOfType("DerivedClassOne") as! DerivedClassOne
dc1.methodOfDCOne()
anObject = dc1
case "TypeTwo":
let dc2 = self.giveMeAnObjectOfType("DerivedClassTwo") as! DerivedClassTwo
dc2.methodOfDCTwo()
anObject = dc2
default:
// Throw a tantrum here
fatalError("Unexpected type")
}
return anObject
}