Como extender clases en JS o usar herencia en clases


En un artículo anterior escribí sobre como utilizar clases en JavaScript, pero una de las mejores partes de trabajar con clases es la habilidad de poder heredar código de otras clases. En este articulo te explico como se usa la herencia en JavaScript.

NOTA: Durante este articulo vamos a tomar como base el código de esta clase, para desarrollar todos los ejemplos de herencia.

class Mascota {
  //Definir un constructor para inicializar variables
  constructor(nombre)
  {
    this.nombre = nombre;
  };

  //Ejemplo de un metodo
  saludar()
  {
    console.log("Hola, mi nombre es " + this.nombre);
  }
};

Como extender una clase (herencia).

Para heredar o extender una clase, debemos usar la palabra extends seguida de la clase que deseamos tomar como base. Por ejemplo, con este código creamos una clase llamada Gato con todas las propiedades y métodos de la clase Mascota:

class Gato extends Mascota {};

Podemos probar el código anterior creando un objeto de la clase Gato y comprobar que ha heredado todo el código de su clase base Mascota, aquí hay un ejemplo completo:

class Mascota {
  //Definir un constructor para inicializar variables
  constructor(nombre)
  {
    this.nombre = nombre;
  };

  //Ejemplo de un método
  saludar()
  {
    console.log("Hola, mi nombre es " + this.nombre);
  }
};

//Ejemplo de herencia
class Gato extends Mascota {};

//Crear un objeto de la clase gato
const tom = new Gato("Tom");
tom.saludar();

Como agregar parámetros adicionales al constructor de la clase

La idea detrás de la herencia es crear clases más complejas y posiblemente necesites más información para crear un objeto de una clase extendida, por eso aquí hay un ejemplo de como agregar más parámetros al constructor sin afectar a la clase base.

//Ejemplo de herencia
class Gato extends Mascota {
 // Sobreescribir el constructor para agregar un parametro  
 constructor(nombre, edad) {
  super(nombre); //Llama al constructor de la clase base
  this.edad = edad;
 }
}

En el código anterior extendemos la clase base Mascota y además definimos nuevamente el constructor, al hacer esto reemplazamos totalmente el constructor heredado de la clase base, sin embargo, podemos rescatarlo al ejecutar la función super y enviando el parámetro que necesita, de esta forma se ejecuta el código del constructor de la clase base.

Como sobreescribir los métodos de la clase base.

Sabemos que cuando extiendes una clase, heredas todo de la clase base, pero si lo deseas puede sobre rescribir cualquier parte, incluso los métodos simplemente volviéndolos a definir, aquí hay un ejemplo:

class Mascota {
  //Definir un constructor para inicializar variables
  constructor(nombre)
  {
    this.nombre = nombre;
  };

  //Ejemplo de un metodo
  saludar()
  {
    console.log("Hola, mi nombre es " + this.nombre);
  }
};

//Ejemplo de herencia
class Gato extends Mascota {
 // Sobreescribir el constructor para agregar un parametro
 constructor(nombre, edad) {
  super(nombre); //Llama al constructor de la clase base
  this.edad = edad;
 }

 // Sobre escribir el metodo saludar
 saludar(){
   console.log("Hola, mi nombre es " + this.nombre);
   console.log(`Tengo ${this.edad} años`)
 }
}

//Crear un objeto de la clase gato
const tom = new Gato("Tom", "6");
tom.saludar();

Como ampliar un método en una clase extendida, sin perder el código original.

Ahora imagina que heredas un método de una clase y sabes que todo el código de un método esta bien, pero hace falta algo más que deseas agregar.

Ya sabes que puedes volver a definirlo pero pierdes el código de la clase base, pero aún puedes llamar al método original usando el objeto super de esta forma super.metodo(). Aquí hay un ejemplo completo:

class Mascota {
  //Definir un constructor para inicializar variables
  constructor(nombre)
  {
    this.nombre = nombre;
  };

  //Ejemplo de un metodo
  saludar()
  {
    console.log("Hola, mi nombre es " + this.nombre);
  }
};

//Ejemplo de herencia
class Gato extends Mascota {
 // Sobreescribir el constructor para agregar un parametro
 constructor(nombre, edad) {
  super(nombre); //Llama al constructor de la clase base
  this.edad = edad;
 }

 // Sobre escribir el metodo saludar
 saludar(){
   super.saludar(); //Reusar el codigo de la clase base
   console.log(`Tengo ${this.edad} años`)
 }
}

//Crear un objeto de la clase gato
const tom = new Gato("Tom", "6");
tom.saludar();