Inheritance

Inheritance is ability to define a new classes as extensions of an existing class. As a result, we reuse existing code and can use child classes wherever the parent class can be used.

Only classes (not structures) can participate in inheritance.

By default all classes can be parent to other classes. You can apply the final modifier to a class to prevent inheriting from it.

class Vehicle { // base class
    var currentSpeed = 0.0
    var description: String {
        return "traveling at \(currentSpeed) miles per hour"
    }
    func makeNoise() {
        // do nothing - an arbitrary vehicle doesn't necessarily make a noise
    }
}

class Bicycle: Vehicle { // child class
    var hasBasket = false
}

let bicycle = Bicycle()
print("\(bicycle.hasBasket), speed: \(bicycle.currentSpeed)") 

polymorphism

The override keyword is used to ensure that you are overriding a method/property/subscript and not defining a new one.

You can apply the final modifier to a property/method/subscription to prevent overriding it.

super is a special predefined property, that refers to the parent class. Typically it is used for overriding methods in subclasses.

For safety reasons, Swift always makes you call one of the parent init from child classes.

class Train: Vehicle {
    var numberOfWagons :Int
    
    override func makeNoise() { print("Choo Choo") }
    
    override var currentSpeed: Double {
        didSet { /* ... */ }
    }

    override var description: String {
        return super.description + " wagons: \(numberOfWagons)"
    }

    override init() {
        super.init()
        numberOfWagons = 10
    }
}