La herencia en programación orientada a objetos permite crear nuevas clases a partir de una base para reutilizar código, extender funcionalidades y mantener una jerarquía clara. Aquí verás cómo una clase Habit sirve de base para una subclase TimedHabit que añade minutos objetivo, valida entradas y sobrescribe métodos para mostrar información completa.
¿Qué es la herencia en programación orientada a objetos y por qué reutiliza código?
La idea central: una clase base comparte sus propiedades y métodos con sus subclases. El ejemplo del transcript usa la analogía de vehículo, automóvil y motocicleta para mostrar una relación es-un: el automóvil y la motocicleta son vehículos, pero con rasgos propios. Así, una subclase hereda lo común y añade lo específico sin modificar la base.
Herencia: compartir constructor, métodos y propiedades de la clase base.
Polimorfismo: tratar objetos de distintas subclases como si fueran de la clase base.
Extensión: agregar capacidades sin tocar la implementación original.
Palabras clave: extends para heredar. super para inicializar la base. override al sobrescribir un método.
¿Cómo crear la subclase TimedHabit con getters, setters y validación?
El objetivo es añadir a Habit un campo privado de minutos objetivo. Con extends heredamos todo y con super inicializamos lo común. Luego usamos getter y setter para encapsular y validar que los minutos sean positivos.
¿Cómo se define la clase base habit y su método toDisplayString?
La base muestra el nombre y la frecuencia del hábito.
classHabit{constructor(protected name:string,protected frequency:string// p. ej., 'daily'.){}// Muestra información básica del hábito.toDisplayString():string{return`${this.name} - ${this.frequency}`;}}
¿Cómo extender habit con TimedHabit usando extends y super?
La subclase añade minutos objetivo con validación y sobrescribe el método de despliegue para incluirlos.
classTimedHabitextendsHabit{private _targetMinutes!:number;// campo privado.constructor(name:string, frequency:string, targetMinutes:number){super(name, frequency);// inicializa Habit: name y frequency.this.targetMinutes= targetMinutes;// usa el setter para validar.}gettargetMinutes():number{returnthis._targetMinutes;}settargetMinutes(value:number){const minutes =Number(value);if(Number.isNaN(minutes)|| minutes <=0){thrownewError('El objetivo de tiempo debe de ser un número positivo');}this._targetMinutes= minutes;}// override del método para incluir minutos.toDisplayString():string{const baseString =super.toDisplayString();return`${baseString} - ${this.targetMinutes} minutos`;}}
Encapsulación: el campo privado protege el estado.
Validación: asegura un número positivo antes de asignar.
Sobrescritura: combina el resultado base con los minutos.
¿Cómo probar la herencia con console.log e instanceof?
Se sugiere probar en la inicialización de la app y validar en consola. También se muestra cómo detectar errores comunes de escritura (typos) apoyándote en el editor.
Creé la clase SessionHabit que extiende de Habit. Así aproveché la herencia para reutilizar las propiedades de name y frequency llamando a super() en el constructor, evitando duplicar código.
Apliqué encapsulamiento creando la propiedad privada #targetSessions protegida por un setter que valida que el objetivo sea un número positivo, y un getter para que nos muestre el valor después de su prueba.
Usé el polimorfismo sobrescribiendo el método toDisplayString(), combinando el texto base de la clase padre Habit PERO devolviendo un resultado diferente aplicado a la clase hija SessionHabit.
classSessionHabitextendsHabit{//Guardaremos en secreto las sesiones en una cajita privada llamada targetSessions #targetSessions
constructor(name,frequency,targetSessions){super(name,frequency)//El padre guarda el nombre y la frecuenciathis.targetSessions= targetSessions // yo guardaré las sesiones }// El getter solo sirve para que el mundo exterior pueda leer el número sin modificarlogettargetSessions(){returnthis.#targetSessions}// EL GUARDIA DE SEGURIDAD, SI NO CUMPLES CON LO QUE TE DIGO NO INGRESASsettargetSessions(value){const sessions =Number(value)// Si no es un número, o es menor o igual a cero... ¡ERROR!if(isNaN(sessions)|| sessions <=0){thrownewError('El objetivo de sesiones debe ser un número positivo')}// Si todo está bien, lo guardamos en nuestra cajita privadareturnthis.#targetSessions= sessions
}toDisplayString(){const baseString =super.toDisplayString()// recibe LEER - WEEKLYreturn`${baseString} - ${this.#targetSessions} sesiones`// DEVUELVE "LEER - WEEKLY"}}// PRUEBA AL FINAL DEL CÓDIGO try{const miMetaSemanal =newSessionHabit("Ir al gimnasio","weekly",3);console.log(miMetaSemanal.toDisplayString());// Imprimirá en consola: "Ir al gimnasio - weekly - 3 sesiones"}catch(error){console.error(error.message);}