Qu’est-ce que le polymorphisme? Et pourquoi cela vaut la peine d’apprendre

Si vous pouvez conduire une voiture de banlieue 4 portes, vous pouvez également conduire une camionnette. Si vous avez conduit une voiture avec un moteur à combustion, vous pouvez également conduire une voiture électrique.

La forme et la taille des véhicules de tourisme peuvent être différentes de l'une à l'autre. Le moteur qui fait fonctionner ces véhicules pourrait également être complètement différent. Mais cela n'a pas d'importance pour le conducteur.

Il vous suffit de monter, d'attacher votre ceinture, de démarrer le véhicule, de le mettre en marche et de conduire. C'est parce que les voitures, les camions et les fourgonnettes sont polymorphes .

Polymorphisme: le décomposer

Regardons le mot polymorphisme. Vous pouvez le décomposer en poly , morph et isme .

Poly signifie plusieurs, comme la façon dont polygone signifie plusieurs angles. Lorsqu'il est utilisé comme nom, un morph est une variante d'une espèce. Et isme peut signifier système.

Ainsi, le polymorphisme signifie simplement un système de nombreuses variantes. Cela ne vous dit toujours pas grand-chose sur la façon dont il est utilisé dans la programmation, cependant. C'est la prochaine.

S'il marche comme un canard … Pourquoi les objets polymorphes sont géniaux

Lorsque vous créez une classe dans votre code qui hérite d'une autre classe, vous liez la nouvelle classe à un contrat. Le contrat stipule que chaque variable et fonction dans le parent sera également dans l'enfant.

Chaque véhicule est équipé d'un volant, de pédales d'accélérateur et de frein et d'un clignotant. Vous n'avez pas besoin d'ouvrir le capot pour conduire une voiture. Tout ce qui compte, c'est que ce soit une voiture.

La même chose s'applique aux classes qui héritent d'autres classes. Voici un exemple dans TypeScript:

 
class Vehicle {
private _engine: string;
private _tires: number;
constructor(engine: string = "combustion", tires: number = 4) {
this._engine = engine;
this._tires = tires;
}
accelerate(velocity: number) {
console.log("accelerating at a velocity of " + velocity);
}
brake(pressure: number) {
console.log("applying " + pressure + " pressure");
}
turnLeft() {
console.log("turning left");
}
turnRight() {
console.log("turning right");
}
}
class Car extends Vehicle {
}
class Tesla extends Car {
constructor() {
super("electric");
}
}

Dans cet exemple, il existe une classe Vehicle . La classe Car hérite de la classe Vehicle . Et Tesla hérite de Car . Créons maintenant quelques objets et regardons-les.

 let myCoupe: Car = new Vehicle();
console.log(myCoupe);
console.log(myCoupe.constructor.name);
let mySedan: Vehicle = new Tesla();
console.log(mySedan);
console.log(mySedan.constructor.name);
myCoupe.turnLeft();
mySedan.turnLeft();

Vous pouvez voir que nous avons déclaré myCoupe comme une voiture et mySedan comme un véhicule . Ensuite, nous avons instancié myCoupe en tant que nouveau véhicule et mySedan en tant que nouvelle Tesla . Si vous visitez le bac à sable TypeScript et exécutez le code, vous verrez qu'il fonctionne sans erreur . Et il se comporte comme vous vous en doutez, en fonction du contrat.

En d'autres termes, tous les véhicules peuvent tourner à gauche car ils l'ont hérité de la classe Véhicule . Le compilateur sait que chaque enfant de Vehicle a accepté le contrat. Il suppose donc que tout va bien, quelles que soient les classes dans lesquelles les objets ont été typés ou instanciés.

Ceci est parfois appelé «frappe de canard». Le compilateur suppose que s'il marche comme un canard et parle comme un canard, il pourrait aussi bien être un canard. Ainsi, le compilateur ne se soucie pas des détails et traite simplement l'objet comme un canard.

Le polymorphisme rend votre code à l'épreuve des balles

Un autre avantage du contrat de polymorphisme est la garantie que votre code fonctionnera. Si vous avez fortement tapé toutes vos variables et ce que chaque fonction renvoie, vous savez que chaque enfant correspondra toujours aux variables, fonctions et types.

Cela signifie que vous pouvez ajouter et modifier le code de vos classes sans interrompre votre programme. Chaque objet qui fait référence à un objet Vehicle obtiendra toujours des données et des fonctionnalités qui répondent aux attentes, quel que soit le nombre de changements de Car .

Le code à l'intérieur de la fonction peut ne pas donner les résultats corrects. Mais c'est un autre type de problème. Tant que la fonction suit le contrat et renvoie le type de variable attendu, cela n'entraînera pas d'erreur de rupture de code.

Le polymorphisme est énorme, et voici 10 autres principes de programmation que vous devriez connaître .

Pratiquer le polymorphisme

  • Utilisez le lien sandbox ci-dessus pour créer une classe de bateau .
  • Instanciez un nouvel objet bateau de manière à ce qu'il soit de type Véhicule , mais ressemble toujours à un bateau.
  • Assurez-vous que le bateau se comporte toujours comme un véhicule.

Un dernier exemple de polymorphisme

Le polymorphisme peut être un concept délicat à saisir au départ. Mais une fois que vous l'avez compris, vous avez fait un grand pas en avant pour comprendre ce qu'est vraiment la programmation orientée objet. Le concept peut cependant sembler théorique. Voici donc un exemple concret solide pour vous aider à voir à quel point il est utile.

Imaginez que vous construisez une application Web qui se connecte à une base de données MySQL. Ensuite, le patron décide de passer à une base de données PostgreSQL. Cela signifie-t-il que vous devez réécrire tous vos appels à la base de données?

Non, ce n'est pas le cas. Si votre application utilise une classe DataAccess avec des sous-classes qui se moquent des données, vous avez de la chance. La classe DataAccess définit comment votre application interagit avec les données, et non comment elle interagit avec la base de données.

Vous avez des sous-classes comme MySQLAccess et PostgresQLAccess qui font tout le sale boulot. Mais si votre application ne contient que des objets DataAccess , vous pouvez échanger des bases de données sans réécrire une seule ligne de code d'application.