Overriding superclass property with different type in Swift

Swift does not allow you to change the class type of any variables or properties. Instead you can create an extra variable in the subclass that handles the new class type:

class Chassis {}
class RacingChassis : Chassis {}

class Car {
    var chassis = Chassis()
}
class RaceCar: Car {
    var racingChassis = RacingChassis()
    override var chassis: Chassis {
        get {
            return racingChassis
        }
        set {
            if let newRacingChassis = newValue as? RacingChassis {
                racingChassis = newRacingChassis
            } else {
                println("incorrect chassis type for racecar")
            }
        }
    }
}

It seems one cannot declare a property with the let syntax and override it with var in it’s subclass or vice-versa, which may be because the superclass implementation might not be expecting that property to change once initialized. So in this case the property needs to be declared with ‘var’ in the superclass as well to match the subclass (as shown in the snippet above). If one cannot change the source code in the superclass then its probably best to destroy the current RaceCar and create a new RaceCar every time the chassis needs to be mutated.


Try this:

class Chassis{
     var chassis{
         return "chassis"
     } 
}

class RacingChassis:Chassis{
     var racing{
         return "racing"
     } 
}

class Car<Type:Chassis> {
     let chassis: Type
     init(chassis:Type){
        self.chassis = chassis
     }
}

class RaceCar: Car<RacingChassis> {
     var description{
         return self.chassis.racing
     } 
}

Then:

let racingChassis = RacingChassis()
let raceCar = RaceCar(chassis:racingChassis)
print(raceCar.description) //output:racing

Detail in http://www.mylonly.com/14957025459875.html


Theoretically, you're allowed to do it this way...

class ViewController {

    var view: UIView! { return _view }

    private var _view: UIView!
}

class ScrollView : UIView {}

class ScrollViewController : ViewController {

    override var view: ScrollView! { return super.view as ScrollView! }
}

class HomeView : ScrollView {}

class HomeViewController : ScrollViewController {

    override var view: HomeView! { return super.view as HomeView! }
}

This works perfectly in an Xcode playground.

But, if you try this in a real project, a compiler error tells you:

Declaration 'view' cannot override more than one superclass declaration

I've only checked Xcode 6.0 GM as of now.

Unfortunately, you'll have to wait until Apple fixes this.

I've submitted a bug report too. 18518795


This seems to work

class Chassis {
    func description() -> String {
        return "Chassis"
    }
}
class RacingChassis : Chassis {
    override func description() -> String {
        return "Racing Chassis"
    }

    func racingChassisMethod() -> String {
        return "Wrooom"
    }
}

class Car {
    let chassis = Chassis()
}
class RaceCar: Car {
    override var chassis: RacingChassis {
    get {
        return self.chassis
    }
    set {
        self.chassis = newValue
    }
    }
}

var car = Car()
car.chassis.description()

var raceCar = RaceCar()
raceCar.chassis.description()
raceCar.chassis.racingChassisMethod()

Tags:

Swift