Hé

Héritage en JavaScript

1 exercice

À propos de Héritage

L'héritage est un moyen de créer des relations parent-enfant entre les classes. La classe enfant (parfois appelée sous-classe) a accès au comportement et aux données définis par la classe parente (parfois appelée superclasse).

class Pet {
  constructor(name) {
    this.name = name;
  }

  introduce() {
    console.log(`This is my pet, ${this.name}.`);
  }
}

class Dog extends Pet {}

const dog = new Dog('Otis');
dog.introduce();
// => This is my pet, Otis.

Le mot-clé extends dans la déclaration de la classe enfant établit une relation avec la classe parente via la chaîne de prototypes.

Les objets créés par le constructeur de la classe enfant ont le prototype de la classe parente dans leur chaîne de prototypes, ce qui leur donne accès à toutes les méthodes et données définies par la classe parente.

const dog = new Dog('Otis');

Dog.prototype.isPrototypeOf(dog); // => true
Pet.prototype.isPrototypeOf(dog); // => true
Pet.prototype.isPrototypeOf(Dog.prototype); // => true

Pet.prototype.hasOwnProperty('introduce'); // => true
Dog.prototype.hasOwnProperty('introduce'); // => false
dog.hasOwnProperty('introduce'); // => false

Les constructeurs

Si la classe enfant ne définit pas de constructeur, c'est celui de la classe parente qui est utilisé. En revanche, si la classe enfant définit son propre constructeur, elle doit appeler explicitement le constructeur parent. Pour appeler le constructeur parent depuis le constructeur enfant, on utilise le mot-clé super.

class Pet {
  constructor(name) {
    this.name = name;
  }
}

class Dog extends Pet {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }
}

const dog = new Dog('Otis', 'Pug');

Comme le constructeur parent se charge d'initialiser un nouvel objet et de l'affecter à this, il faut l'appeler avant que le constructeur enfant n'utilise this.

class Dog extends Pet {
  constructor(name, breed) {
    // using 'this' before calling the parent constructor with 'super'
    this.breed = breed;
    super(name);
  }
}

const dog = new Dog('Otis', 'Pug');
// => ReferenceError: Must call super constructor in derived class before accessing 'this'...

Définir des méthodes sur la classe enfant

Une classe enfant peut définir son propre comportement en plus de celui qu'elle hérite de la classe parente.

C'est l'une des raisons principales d'utiliser l'héritage : disposer de classes enfants spécialisées, avec leurs propres données et méthodes, reliées entre elles par les méthodes et les données partagées fournies par la classe parente.

class Dog extends Pet {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }

  describe() {
    console.log(`${this.name} is a ${this.breed}.`);
  }
}

const dog = new Dog('Otis', 'Pug');
dog.introduce();
dog.describe();
// => 'This is my pet, Otis.'
// => 'Otis is a Pug.'

Redéfinir les méthodes héritées de la classe parente

Une classe enfant peut aussi redéfinir le comportement d'une méthode définie par la classe parente et le remplacer ou l'étendre par un comportement défini par la classe enfant.

class Cat extends Pet {
  // replacing parent class behavior
  introduce() {
    console.log(`This is my cat, ${this.name}.`);
  }
}

class Dog extends Pet {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }

  describe() {
    console.log(`${this.name} is a ${this.breed}.`);
  }

  // extending parent class behavior
  introduce() {
    super.introduce();
    this.describe();
  }
}

const cat = new Cat('Milo');
cat.introduce();
// => 'This is my cat, Milo.'

const dog = new Dog('Otis', 'Pug');
dog.introduce();
// => This is my pet, Otis.
// => Otis is a Pug.

Pour appeler, depuis le corps d'une méthode de la classe enfant, une méthode de même nom définie sur la classe parente, il faut utiliser le mot-clé super pour faire référence à la classe parente.

Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet

Apprends Héritage