Domina la herencia en Swift con ejemplos claros: aprende a sobrescribir métodos y propiedades con override, a combinar resultados con super, a usar observers como didSet para lógica reactiva y a proteger APIs con final para evitar cambios en subclases. Todo con el caso de Vehicle, Train, Car y AutomaticCar.
¿Cómo funciona la sobrescritura en Swift?
Sobrescribir en Swift implica redefinir en la subclase lo que la clase padre ya tiene. Con la palabra reservada override indicas que tu implementación reemplaza la del padre y será la que se ejecute.
Usa override en métodos y propiedades computadas.
Lo del padre no se ejecuta, a menos que invoques super.
Si la subclase no implementa override, hereda el comportamiento del padre.
¿Qué cambia al sobrescribir métodos como makeNoise?
En el ejemplo, el tren redefine el sonido con override. Así el método del hijo se ejecuta en lugar del del padre.
classVehicle{var currentSpeed:Double=0.0var description:String{"Viajando a \(currentSpeed) kilómetros por hora"}funcmakeNoise(){print("El ruido depende del vehículo")}}classTrain:Vehicle{overridefuncmakeNoise(){print("chu, chu")}}let train =Train()train.makeNoise()// chu, chu
Idea clave:override sustituye la implementación del padre.
Si otra subclase, como Tandem, no hace override, ejecuta la del padre: "El ruido depende del vehículo".
¿Qué sucede si no hay override en la subclase?
El método del padre se utiliza sin cambios.
Útil cuando varias subclases comparten el mismo comportamiento base.
Puedes decidir si una subclase reutiliza al padre o añade su propia lógica.
¿Cómo sobrescribir properties, getters/setters y observers?
Además de métodos, puedes sobrescribir propiedades computadas y sus getters/setters, e incluso observers como didSet, para ajustar la lógica cuando cambia el estado.
¿Cómo combinar super.description con información extra?
El coche añade una propiedad gear y enriquece la descripción usando super.description.
classCar:Vehicle{var gear:Int=1overridevar description:String{returnsuper.description +" en la marcha \(gear)"}}let car =Car()car.currentSpeed =55car.gear =3print(car.description)// Viajando a 55 kilómetros por hora en la marcha 3
Patrón común: toma lo del padre con super y agrega contexto propio.
Mantiene coherencia y evita duplicar lógica.
¿Cómo ajustar gear automáticamente con didSet?
El coche automático calcula la marcha en función de la velocidad con un observer.
classAutomaticCar:Car{overridevar currentSpeed:Double{didSet{ gear =Int(currentSpeed /15.0)+1}}}let automatic =AutomaticCar()automatic.currentSpeed =35print(automatic.description)// ... en la marcha 3automatic.currentSpeed =55print(automatic.description)// ... en la marcha 4automatic.currentSpeed =65print(automatic.description)// ... en la marcha 5
Lógica reactiva:didSet responde a cambios en tiempo real.
Fórmula simple y legible: velocidad/15.0 más 1.
¿Cómo evitar que una subclase sobrescriba con final?
Cuando no quieres que una API cambie en herencias, marca métodos o propiedades como final. Así, ninguna subclase podrá sobrescribirlos.
¿Qué implica marcar una property como final?
Si el tren fija un dato que no debe cambiar en subclases, usa final.
classTrain:Vehicle{finalvar numberOfWagons:Int=0overridefuncmakeNoise(){print("chu, chu")}}classRailway:Train{// override var numberOfWagons: Int = 10// Error: property does not override any property from its superclass}
Protección de diseño:final impide cambios indeseados en herencia.
Aplica a métodos, propiedades, subscripts y también a métodos estáticos declarados con class.
¿Te gustaría ver más variantes con Bicycle o Tandem y decidir cuándo usar el del padre o su propio override? Cuéntame en comentarios qué implementarías y por qué.