3
class Car {
     func upgrade() -> Car { 
        return Car()
     }
}


class RacingCar : Car {

}

let racingCar = RacingCar()
let upgradedRacingCar = racingCar.upgrade()
// ideally upgradedRacingCar should be a RacingCar

How to make the upgrade method create RacingCar objects if its called on a subclass, without implementing it in the RacingCar?

bogen
  • 9,954
  • 9
  • 50
  • 89
  • Related: [Protocol func returning Self](http://stackoverflow.com/questions/25645090/protocol-func-returning-self) – Martin R May 14 '15 at 20:41

1 Answers1

5

Like this. If it's a class method:

class Car {
    class func upgrade() -> Self { 
        return self()
    }
}

If it's an instance method:

class Car {
    func upgrade() -> Self { 
        return self.dynamicType()
    }
}

The return type Self means "the class of me, polymorphically". So we return a Car if this is Car and a RacingCar if this is RacingCar. The notation self() and self.dynamicType() are shorthand for calling init; these are both classes, so that's legal. I presume you will have a more elaborate initializer. You will have to make your initializer required to calm the fears of the compiler (as I explain here); thus, neither of the above will compile unless init() is marked required in Car.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • And see my book, which covers this exact situation: http://www.apeth.com/swiftBook/ch04.html#_type_reference – matt May 14 '15 at 20:42