Héritage multiple dans TypeScript

Migel Hewage Nimesha 30 janvier 2023
  1. Héritage unique dans TypeScript
  2. Héritage multiple avec des classes TypeScript
  3. Héritage multiple avec les interfaces TypeScript
  4. Héritage multiple avec des mixins TypeScript
Héritage multiple dans TypeScript

Il existe plusieurs paradigmes de programmation qui ont évolué au fil des ans. La programmation orientée objet (POO) est l’un des principaux paradigmes basés sur des entités du monde réel et leur interaction.

L’héritage est l’un des concepts bien connus de la POO qui permet d’acquérir les propriétés et les comportements de l’entité mère par des sous-entités.

Héritage unique dans TypeScript

TypeScript prend en charge les techniques OOP dans une certaine mesure. Il prend en charge l’héritage d’une entité parente, permettant aux programmeurs de réutiliser leur code efficacement.

Nous pouvons hériter d’une entité parente en utilisant le mot-clé extends, comme indiqué ci-dessous.

class Animal {
    constructor() {
        console.log("Animal class");
    }
}

class Cat extends Animal {

    constructor() {
        super();
    }
}

const cat = new Cat();

Production:

"Animal class"

C’est ce qu’on appelle l’héritage unique que la classe donnée ne peut étendre qu’à une seule classe parent.

Héritage multiple avec des classes TypeScript

Il est possible d’acquérir des propriétés et des comportements à partir de plusieurs entités parentes dans des langages de type Java. C’est ce qu’on appelle l’héritage multiple.

TypeScript ne prend pas en charge l’héritage multiple.

Héritage multiple

Essayons d’étendre plusieurs classes parentes dans TypeScript en utilisant extends.

class Engineer {
    constructor() {
        console.log("Employee class");
    }
}

class Person {
    constructor() {
        console.log("Person class");
    }
}

class Employee extends Engineer, Person {
}

Ensuite, transpilons le code TypeScript, comme indiqué ci-dessous.

tsc example1.ts

Production:

Héritage multiple TypeScript - Sortie 1

Comme prévu, cela donne une erreur indiquant que TypeScript n’autorise l’extension que d’une seule classe.

Héritage multiple avec les interfaces TypeScript

Les interfaces TypeScript prennent en charge l’héritage multiple prêt à l’emploi. Ils peuvent étendre plus d’une classe.

Créons deux classes, Person et Engineer, et ajoutons quelques méthodes factices.

class Person {
    name: string;

    constructor() {
       console.log("Person class");
    }

    sayImAPerson(){
        console.log("Hey, I am a person");
    }
}

class Engineer {
    salary: number;
    constructor() {
        console.log("Engineer class");
    }
    sayImAnEngineer(){
        console.log("I am an engineer too");
    }
}

Ensuite, nous allons créer un nouveau type ou une nouvelle classe pour étendre les deux classes ci-dessus.

class Employee {
    empId: string;
}

Étant donné que la classe Employee ne peut pas étendre plus d’une classe parente, nous devons utiliser une interface portant le même nom Employee pour utiliser la fusion des déclarations TypeScript. De cette façon, vous pouvez fusionner des interfaces et des classes.

Créons l’interface Employee, qui étend les classes Person et Engineer, comme indiqué ci-dessous.

interface Employee extends Person, Engineer {
}

Transpilons le code TypeScript et vérifions si nous obtenons des erreurs.

Production:

Héritage multiple TypeScript - Sortie 2

Comme prévu, il n’y a pas d’erreurs lors de l’utilisation de extends avec plus d’une classe parente dans la déclaration d’interface. Par conséquent, l’interface prend en charge plusieurs héritages.

Mais il y a toujours un problème si nous appelons une méthode à l’intérieur de la classe héritée. Nous n’avons pas accès aux implémentations de la méthode.

Essayons d’appeler la méthode sayImAnEngineer().

let emp: Employee = new Employee;
emp.sayImAnEngineer();

Nous devrions d’abord transpiler le code ; cela ne donnera aucune erreur. Ensuite, essayez d’exécuter le JavaScript généré ; cela générerait une erreur, comme indiqué dans la sortie suivante.

Production:

Héritage multiple TypeScript - Sortie 3

TypeScript n’a pas pu localiser la méthode sayImAnEngineer. Nous pouvons surmonter cela en utilisant des mixins TypeScript.

Héritage multiple avec des mixins TypeScript

Le mécanisme de mixins TypeScript peut copier toutes les méthodes disponibles dans les classes parentes vers la classe ou la sous-classe dérivée. La méthode de création de mixin doit parcourir toutes les propriétés des classes parentes et récupérer le contenu.

Ensuite, il doit définir tout le contenu de la classe dérivée tel quel. Il existe une méthode fournie par la documentation officielle de TypeScript : mixin creation method.

Il est recommandé de l’utiliser dans votre fichier TypeScript, comme indiqué ci-dessous.

function applyMixins(derivedCtor: any, constructors: any[]) {
  constructors.forEach((baseCtor) => {
    Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
      Object.defineProperty(
        derivedCtor.prototype,
        name,
        Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||
          Object.create(null)
      );
    });
  });
}

Incluons la méthode applyMixins dans notre exemple TypeScript.

class Person {
    name: string;

    constructor() {
       console.log("Person class");
    }

    sayImAPerson(){
        console.log("Hey, I am a person");
    }
}

class Engineer {
    salary: number;
    constructor() {
        console.log("Engineer class");
    }
    sayImAnEngineer(){
        console.log("I am an engineer too");
    }
}

class Employee {
    empId: string;
}

interface Employee extends Person, Engineer {

}

function applyMixins(derivedCtor: any, constructors: any[]) {
  constructors.forEach((baseCtor) => {
    Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
      Object.defineProperty(
        derivedCtor.prototype,
        name,
        Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||
          Object.create(null)
      );
    });
  });
}

Appelons maintenant la méthode applyMixins, comme illustré ci-dessous.

applyMixins(Employee, [Person, Engineer]);

Le premier paramètre doit être la classe dérivée ; dans ce cas, il s’agit de la classe Employee. Le paramètre suivant est un tableau qui contient toutes les classes parentes que la classe dérivée étendrait.

Enfin, créons un objet Employee et appelons la méthode sayImAnEngineer à partir de la classe parent Engineer.

let emp: Employee = new Employee;
emp.sayImAnEngineer();

Production:

Héritage multiple TypeScript - Sortie 4

Il n’y a pas d’erreurs cette fois ; cela signifie que la technique des mixins a fonctionné. De cette façon, vous pouvez implémenter les héritages multiples dans TypeScript.

Migel Hewage Nimesha avatar Migel Hewage Nimesha avatar

Nimesha is a Full-stack Software Engineer for more than five years, he loves technology, as technology has the power to solve our many problems within just a minute. He have been contributing to various projects over the last 5+ years and working with almost all the so-called 03 tiers(DB, M-Tier, and Client). Recently, he has started working with DevOps technologies such as Azure administration, Kubernetes, Terraform automation, and Bash scripting as well.