4.1 La herencia es sencilla
La herencia es un concepto fundamental de la programación orientada a objetos (OOP), que permite que una clase (llamada clase hija o subclase) herede campos y métodos de otra clase (llamada clase padre o superclase).
Este enfoque permite crear clases más generales y reutilizar el código, mejorando la organización y mantenibilidad del código.
¿Por qué necesitas herencia?
Supongamos que necesitas escribir algún código, y decides hacerlo en forma de clase. Luego descubres que en tu proyecto ya existe una clase que hace casi todo lo que necesitas. Podrías simplemente copiar el código de esa clase en la tuya y usarlo a tu antojo.
O puedes “como quien dice copiarlo”. Puedes declarar esa clase como la clase principal de tu clase, y entonces JavaScript añadirá a tu clase el comportamiento de la clase padre.
Imagina que eres la naturaleza y quieres crear un Perro. ¿Qué sería más rápido: crear un perro de una bacteria en mil millones de años o domesticar un lobo en 200 mil?
4.2 Concepto de herencia a través de prototipos
La herencia a través de prototipos en JavaScript es uno de los mecanismos principales que permite a los objetos heredar propiedades y métodos de otros objetos. Esto permite crear jerarquías de objetos complejas y reutilizar código.
Cada objeto en JavaScript tiene una propiedad oculta [[Prototype]], que apunta a su prototipo. Los prototipos se utilizan para implementar la herencia, lo que permite a los objetos heredar propiedades y métodos de otros objetos.
Ejemplo de herencia simple
Paso 1: Creación de un objeto básico
const animal = {
eat() {
console.log('Eating...');
},
sleep() {
console.log('Sleeping...');
}
};
Paso 2: Creación de un objeto heredero
const dog = Object.create(animal);
dog.bark = function() {
console.log('Barking...');
};
Paso 3: Uso de propiedades y métodos heredados
dog.eat(); // Imprimirá: Eating...
dog.sleep(); // Imprimirá: Sleeping...
dog.bark(); // Imprimirá: Barking...
En este ejemplo, el objeto dog
hereda los métodos eat()
y sleep()
del objeto
animal
y añade su propio método — bark()
.
4.3 Herencia profunda a través de prototipos
Cadena de prototipos
En JavaScript la herencia puede ser más compleja cuando los objetos heredan unos de otros, formando una cadena de prototipos.
Ejemplo de cadena de prototipos
En este ejemplo el objeto dog
hereda de mammal
, que a su vez hereda de
animal
. Esto crea una cadena de prototipos donde dog
tiene acceso a todos los métodos de
mammal
y animal
.
const animal = {
eat() {
console.log('Eating...');
}
};
const mammal = Object.create(animal);
mammal.walk = function() {
console.log('Walking...');
};
const dog = Object.create(mammal);
dog.bark = function() {
console.log('Barking...');
};
dog.eat(); // Imprimirá: Eating...
dog.walk(); // Imprimirá: Walking...
dog.bark(); // Imprimirá: Barking...
Verificación de la cadena de prototipos
El método isPrototypeOf()
permite verificar si un objeto es prototipo de otro objeto.
Ejemplo:
console.log(animal.isPrototypeOf(mammal)); // Imprimirá: true
console.log(mammal.isPrototypeOf(dog)); // Imprimirá: true
console.log(animal.isPrototypeOf(dog)); // Imprimirá: true
4.4 Sobreescritura de métodos
La herencia a través de prototipos permite no solo añadir nuevos métodos, sino también sobrescribir métodos existentes.
Ejemplo de sobrescritura de métodos
En este ejemplo el método speak()
del objeto dog
sobrescribe el método speak()
del objeto animal
:
const animal = {
speak() {
console.log('Animal speaks');
}
};
const dog = Object.create(animal);
dog.speak = function() {
console.log('Dog barks');
};
animal.speak(); // Imprimirá: Animal speaks
dog.speak(); // Imprimirá: Dog barks
Llamada al método del objeto padre
Para llamar al método del objeto padre en JavaScript se puede usar el método call()
o apply()
.
Ejemplo:
const animal = {
speak() {
console.log('Animal speaks');
}
};
const dog = Object.create(animal);
dog.speak = function() {
animal.speak.call(this);
console.log('Dog barks');
};
dog.speak();
// Imprimirá:
// Animal speaks
// Dog barks
4.5 Uso avanzado de la herencia prototípica
Extensión de objetos incorporados
Puedes extender objetos incorporados de JavaScript añadiendo métodos a sus prototipos.
Ejemplo:
Array.prototype.sum = function() {
return this.reduce((acc, value) => acc + value, 0);
};
const numbers = [1, 2, 3, 4, 5];
console.log(numbers.sum()); // Imprimirá: 15
Creación de jerarquías multinivel
Puedes crear jerarquías de objetos más complejas y multinivel utilizando la herencia prototípica.
Ejemplo:
const livingBeing = {
breathe() {
console.log('Breathing...');
}
};
const animal = Object.create(livingBeing);
animal.eat = function() {
console.log('Eating...');
};
const mammal = Object.create(animal);
mammal.walk = function() {
console.log('Walking...');
};
const dog = Object.create(mammal);
dog.bark = function() {
console.log('Barking...');
};
dog.breathe(); // Imprimirá: Breathing...
dog.eat(); // Imprimirá: Eating...
dog.walk(); // Imprimirá: Walking...
dog.bark(); // Imprimirá: Barking...
GO TO FULL VERSION