Tema 7 · Herencia & Super

Herencia con extends y super(): Jerarquías de Clases y Especialización

Aprende a crear subclases especializadas con la palabra clave extends, reutiliza constructores padre con super() y sobrescribe métodos.

Herencia en Clases ES6

La herencia permite que una clase especializada (hija) adquiera todas las propiedades y métodos de una clase más general (padre) mediante la palabra clave extends.

Por debajo, JavaScript configura automáticamente la cadena de prototipos entre ambas clases:
Object.setPrototypeOf(Subclase.prototype, Superclase.prototype).

La Regla de Oro: La Invocación de `super()`

Si tu clase hija define su propio método constructor(), existe una regla estricta e inviolable impuesta por el motor de JavaScript:

¡Regla Obligatoria! Debes llamar a super(...) en la primera línea del constructor de la hija ANTES de intentar usar la palabra clave this.
Si intentas escribir this.algo = valor; antes de super(), JavaScript lanzará un error fatal:
ReferenceError: Must call super constructor in derived class before accessing 'this'

Sobrescritura de Métodos (Method Overriding)

Una clase hija puede redefinir un método heredado para especializar su comportamiento, e incluso invocar el método original del padre usando super.nombreMetodo():

class Gerente extends Empleado {
    obtenerDetalles() {
        // Llama al método del padre y le añade datos adicionales
        return `${super.obtenerDetalles()} [Departamento: ${this.departamento}]`;
    }
}

⚡ Jerarquía de Empleados y Directores con extends y super()

Ejecuta el código en el Sandbox y observa cómo Director especializa el cálculo salarial y métodos heredados:

HerenciaES6.js
Solo lectura
// 1. Superclase Padre
class Empleado {
    constructor(id, nombre, salarioBase) {
        this.id = id;
        this.nombre = nombre;
        this.salarioBase = salarioBase;
    }

    calcularSueldoNeto() {
        // Deducción estándar del 10% de impuestos
        return parseFloat((this.salarioBase * 0.90).toFixed(2));
    }

    obtenerFicha() {
        return `[ID #${this.id}] ${this.nombre} | Salario Base: $${this.salarioBase.toFixed(2)} | Neto: $${this.calcularSueldoNeto().toFixed(2)}`;
    }
}

// 2. Subclase Hija que Especializa a Empleado
class Director extends Empleado {
    constructor(id, nombre, salarioBase, bonoGestion, departamento) {
        // 1er paso obligatorio: Delegar datos al constructor padre
        super(id, nombre, salarioBase);

        // 2do paso: Inicializar propiedades exclusivas de Director
        this.bonoGestion = bonoGestion;
        this.departamento = departamento;
    }

    // Sobrescritura de Método (Override)
    calcularSueldoNeto() {
        // Reutilizamos el neto del padre y sumamos el bono de gestión
        const sueldoBaseNeto = super.calcularSueldoNeto();
        return parseFloat((sueldoBaseNeto + this.bonoGestion).toFixed(2));
    }

    // Sobrescritura para enriquecer la ficha
    obtenerFicha() {
        return `${super.obtenerFicha()} | 🌟 Rol: Director de ${this.departamento} (Bono: +$${this.bonoGestion})`;
    }

    aprobarPresupuesto(monto) {
        console.log(` Director [${this.nombre}] aprobó presupuesto de $${monto} para ${this.departamento}.`);
    }
}

// ==========================================
// PRUEBA EN EL SANDBOX
// ==========================================
const desarrollador = new Empleado(101, "Carlos Mendoza", 3000);
const directorTecnico = new Director(102, "Valeria Torres", 6000, 1500, "Ingeniería de Software");

console.log("=== EMPLEADO GENERAL ===");
console.log(desarrollador.obtenerFicha());

console.log("\n=== DIRECTOR (CON HERENCIA Y SUPER) ===");
console.log(directorTecnico.obtenerFicha());
directorTecnico.aprobarPresupuesto(25000);

console.log("\n=== VERIFICACIÓN DE INSTANCIAS ===");
console.log("¿directorTecnico es Director?:", directorTecnico instanceof Director); // true
console.log("¿directorTecnico es Empleado?:", directorTecnico instanceof Empleado); // true (Herencia)
console.log("¿directorTecnico es Object?:", directorTecnico instanceof Object);     // true
Pruébalo tú mismo » Se abre en una nueva pestaña con ejecución en vivo
🧠
Mini-Quiz de Retención
Comprueba tu comprensión antes de pasar a la siguiente lección
1 Pregunta
Pregunta 1
¿Qué sucede si dentro del constructor de una subclase hija intentas usar "this.propiedad = valor" antes de haber llamado a "super()"?
🦉
¿Tienes dudas con este tema?
Sócrates AI puede darte analogías y explicarte este código paso a paso.

🚀 ¿Quieres dominar Manual de Programación Orientada a Objetos en JavaScript (POO) y crear proyectos reales?

Aprende arquitectura limpia, desarrollo web moderno, buenas prácticas y despliegue en producción con nuestro Bootcamp Fullstack Developer con mentorías en vivo.

🏛️ Autoría y Propiedad Intelectual: Obra educativa original de David Amador para Kilopolis Academia (Solucionáticos), estructurada sobre las especificaciones y estándares abiertos del W3C, el estándar vivo de WHATWG y la documentación oficial de código abierto. © Todos los derechos reservados.