CAP 09 · LEC 02·Programación orientada a objetos

Herencia y super: reutilizar clases existentes

La herencia permite crear clases especializadas basadas en otras, reutilizando propiedades y métodos sin duplicar código.

● INTERMEDIO9 min lectura4 ejerciciospor Fernando Herrera · actualizado mayo de 2026
¿Encontraste un error o algo que mejorar?Editá esta lección en GitHub →

extends: heredar de otra clase

Con extends, una clase hija adquiere todas las propiedades y métodos de la clase padre:

class Animal { constructor(nombre) { this.nombre = nombre; } describir() { return `Soy ${this.nombre}`; } } // Perro hereda todo de Animal class Perro extends Animal { ladrar() { return "¡Guau!"; } } const rex = new Perro("Rex"); console.log(rex.describir()); // "Soy Rex" ← método heredado console.log(rex.ladrar()); // "¡Guau!" ← método propio
class Animal { nombre: string; constructor(nombre: string) { this.nombre = nombre; } describir(): string { return `Soy ${this.nombre}`; } } // Perro hereda todo de Animal class Perro extends Animal { ladrar(): string { return "¡Guau!"; } } const rex = new Perro("Rex"); console.log(rex.describir()); // "Soy Rex" ← método heredado console.log(rex.ladrar()); // "¡Guau!" ← método propio
SalidaSoy Rex ¡Guau!
instanceof

Puedes verificar la jerarquía con instanceof: rex instanceof Perrotrue, y también rex instanceof Animaltrue. La instancia es de la clase hija y de todas sus ancestras.

super(): llamar al constructor padre

Cuando la clase hija tiene su propio constructor, debe llamar a super() antes de usar this. Esto inicializa la parte heredada del objeto:

class Animal { constructor(nombre, tipo) { this.nombre = nombre; this.tipo = tipo; } } class Perro extends Animal { constructor(nombre, raza) { // ✅ super() llama al constructor de Animal super(nombre, "mamífero"); // Ahora podemos usar 'this' this.raza = raza; } presentarse() { return `Soy ${this.nombre}, un ${this.raza} (${this.tipo})`; } } const luna = new Perro("Luna", "Beagle"); console.log(luna.presentarse()); // "Soy Luna, un Beagle (mamífero)"
class Animal { nombre: string; tipo: string; constructor(nombre: string, tipo: string) { this.nombre = nombre; this.tipo = tipo; } } class Perro extends Animal { raza: string; constructor(nombre: string, raza: string) { // ✅ super() llama al constructor de Animal super(nombre, "mamífero"); // Ahora podemos usar 'this' this.raza = raza; } presentarse(): string { return `Soy ${this.nombre}, un ${this.raza} (${this.tipo})`; } } const luna = new Perro("Luna", "Beagle"); console.log(luna.presentarse()); // "Soy Luna, un Beagle (mamífero)"
SalidaSoy Luna, un Beagle (mamífero)
super() es obligatorio

Si defines un constructor en la clase hija y no llamas a super() antes de acceder a this, obtendrás un ReferenceError en tiempo de ejecución. TypeScript lo detecta en compilación.

Override: redefinir comportamiento

Una clase hija puede redefinir (override) cualquier método del padre. La versión de la hija tiene prioridad cuando se llama sobre una instancia de la hija:

class Animal { constructor(nombre) { this.nombre = nombre; } hacerSonido() { return "..."; } toString() { return `Animal: ${this.nombre}`; } } class Perro extends Animal { // Override: redefinimos hacerSonido hacerSonido() { return "¡Guau!"; } } class Gato extends Animal { // Override: cada clase define su propio sonido hacerSonido() { return "¡Miau!"; } } const animales = [new Perro("Rex"), new Gato("Michi"), new Perro("Luna")]; for (const animal of animales) { console.log(`${animal.nombre}: ${animal.hacerSonido()}`); } // Rex: ¡Guau! // Michi: ¡Miau! // Luna: ¡Guau!
class Animal { nombre: string; constructor(nombre: string) { this.nombre = nombre; } hacerSonido(): string { return "..."; } } class Perro extends Animal { override hacerSonido(): string { return "¡Guau!"; } } class Gato extends Animal { override hacerSonido(): string { return "¡Miau!"; } } const animales: Animal[] = [new Perro("Rex"), new Gato("Michi"), new Perro("Luna")]; for (const animal of animales) { console.log(`${animal.nombre}: ${animal.hacerSonido()}`); } // Rex: ¡Guau! // Michi: ¡Miau! // Luna: ¡Guau!
SalidaRex: ¡Guau! Michi: ¡Miau! Luna: ¡Guau!
override en TypeScript

La palabra clave override (TypeScript 4.3+) hace explícito que estás redefiniendo un método del padre. Si el método no existe en la clase padre, TypeScript lanzará un error — lo que previene typos difíciles de detectar.

super.metodo(): llamar la implementación del padre

Dentro de un override, puedes llamar la versión del padre usando super.metodo(). Útil para extender, no reemplazar completamente:

class Empleado { constructor(nombre, salarioBase) { this.nombre = nombre; this.salarioBase = salarioBase; } calcularSalario() { return this.salarioBase; } toString() { return `${this.nombre} — Salario: $${this.calcularSalario()}`; } } class Gerente extends Empleado { constructor(nombre, salarioBase, bono) { super(nombre, salarioBase); this.bono = bono; } // Extiende la lógica del padre en lugar de reemplazarla calcularSalario() { const base = super.calcularSalario(); // ← llama al padre return base + this.bono; } } const emp = new Empleado("Carlos", 3000); const ger = new Gerente("Diana", 5000, 1500); console.log(emp.toString()); // "Carlos — Salario: $3000" console.log(ger.toString()); // "Diana — Salario: $6500"
class Empleado { nombre: string; salarioBase: number; constructor(nombre: string, salarioBase: number) { this.nombre = nombre; this.salarioBase = salarioBase; } calcularSalario(): number { return this.salarioBase; } toString(): string { return `${this.nombre} — Salario: $${this.calcularSalario()}`; } } class Gerente extends Empleado { bono: number; constructor(nombre: string, salarioBase: number, bono: number) { super(nombre, salarioBase); this.bono = bono; } override calcularSalario(): number { const base = super.calcularSalario(); // ← llama al padre return base + this.bono; } } const emp = new Empleado("Carlos", 3000); const ger = new Gerente("Diana", 5000, 1500); console.log(emp.toString()); // "Carlos — Salario: $3000" console.log(ger.toString()); // "Diana — Salario: $6500"
SalidaCarlos — Salario: $3000 Diana — Salario: $6500

Practica