M3203 - Programmation objet et événementielle - TP4


Objectifs de la séance

  • Connaître la notion d'héritage en programmation orientée objet
  • Savoir dériver une classe

Pré-requis

  • Savoir créer et manipuler des classes en Javascript

Résumé de la séance précédente

  • Les objets permettent de stocker plusieurs valeurs dans une même variable. Ces valeurs sont appelées propriétés.
  • Les objets possèdent leurs propres fonctions appelées méthodes.
  • Pour accéder à la valeur d'une propriété, on écrit ⟨objet⟩.⟨propriété⟩.
  • Une classe est un modèle d'objet : elle définit toutes ses propriétés et toutes ses méthodes.
  • Une classe possède un constructeur qui initialisera l'objet lors de sa création.
  • Exemple de classe possédant un constructeur et une méthode :

class Balle{
	constructor(valeur){.       // Constructeur de la classe
		this.taille = valeur;	// Initialisation d'une propriété this.taille
		this.couleur = "Black"; // Initialisation d'une propriété this.couleur :
		// toutes les balles seront noires
		this.dessiner();		// On dessinera la balle dès la création de l'objet
	}

	dessiner(){					// Une méthode pour dessiner la balle
		// Du code...
	}
}
								

L'héritage

Définition

En programmation orientée objet, il est possible de créer de nouvelles classes à partir d'autres classes : c'est le concept d'héritage. Les classes filles vont hériter des propriétés et des méthodes de leur classe mère. Cela permet donc d'avoir une classe mère et des classes filles partageant leurs attributs sans avoir à les dupliquer tandis que les classes filles pourront posséder des propriétés et méthodes spécifiques.

Exemple

Illustration : l'économie se porte bien et notre loueur de voitures se développe. 2018 oblige, ses clients lui réclament un service de location de vélos ! L'application de gestion que nous avons créée basée sur la classe Voiture ne convient malheureusement pas du tout à ça. C'est bien dommage : on ne connaissait pas l'héritage, on va devoir retravailler notre modèle.

Réfléchissons, on a maintenant deux types de véhicules à gérer : des voitures et des vélos. Et anticipons : il n'est pas impossible que le loueur revienne nous voir pour implémenter la gestion des scooters ou de véhicules utilitaires... On veut éviter de bousculer nos classes à chaque évolution du logiciel.

Voitures et vélos partagent les caractéristiques de base d'un véhicule : ils possèdent une marque, un modèle, une couleur, et un prix pour la location à la journée. Dans les deux cas, on aura aussi besoin d'afficher ces informations aux clients grâce à une méthode. Regroupons donc ces caractéristiques de base dans une classe Vehicule. Le modèle UML correspond alors à ceci :

Vehicule
modele : String
marque : String
couleur : String
prix : Float
affiche()

On a maintenant notre classe Vehicule qui nous permet de gérer les informations de base. Il nous faut maintenant nous occuper des cas spécifiques de la voiture et du vélo : c'est là que va intervenir l'héritage.

Une voiture est un véhicule qui possède quelques caractéristiques supplémentaires : sa motorisation et la présence d'un autoradio.

Un vélo est un véhicule avec également des caractéristiques spécifiques : son type (vtt ou urbain) et s'il est électrique ou non.

Nos classes Voiture et Velo vont donc hériter de la classe Vehicule et intégrer leurs caractéristiques spécifiques. Cela signifie que Voiture et Velo possèderont toutes les propriétés et méthodes de Vehicule plus leurs propres propriétés et méthodes.

heritage

Dériver une classe en Javascript

Comment écrire ceci en Javascript ? Pour écrire la classe Vehicule, vous savez faire :

class Vehicule{
	constructor(marque, modele, couleur, prix){
		// Constructeur de la classe
		this.marque = marque; // La propriété this.marque est initialisée avec la valeur marque passée en paramètre
		this.modele = modele;
		this.couleur = couleur;
		this.prix = prix; 
	}

	affiche() {
		// La méthode affiche écrit une phrase du type "Marque modele de couleur X est à louer pour YZ euros par jour." dans le document HTML.
		document.write("

" + this.marque + " " + this.modele + " de couleur " + this.couleur + " est à louer pour " + this.prix + " euros par jour."); } }

Le mot-clé extends

Pour dériver une classe en Javascript avec la syntaxe ECMAScript 2015, on utilise le mot-clé extends. Il est utilisé dans les déclarations et expressions de classes afin de signifier qu'un type représenté par une classe hérite d'un autre type.


class Voiture extends Vehicule{
// La classe Voiture hérite de la classe Vehicule

}

class Velo extends Vehicule{
// La classe Velo hérite de la classe Vehicule

}
							

Le mot-clé super

On utilise ensuite le mot-clé super afin d'appeler ou accéder à des fonctions définies sur l'objet parent. Par exemple, le constructeur de Voiture devra faire appel au constructeur de sa classe mère Vehicule pour initialiser les propriétés marque, modele, couleur et prix.


class Voiture extends Vehicule{
// La classe Voiture hérite de la classe Vehicule
	constructor(marque, modele, couleur, prix, motorisation, autoradio) {
		super(marque, modele, couleur, prix); // On appelle le constructeur de la classe mère
		this.motorisation = motorisation; 	  // On initialise les propriétés spécifiques à Voiture
		this.possedeAutoradio = autoradio;
	}
}

class Velo extends Vehicule{
// La classe Velo hérite de la classe Vehicule
	constructor(marque, modele, couleur, prix, type, electrique) {
		super(marque, modele, couleur, prix); // On appelle le constructeur de la classe mère
		this.type = type;					  // On initialise les propriétés spécifiques à Velo
		this.estElectrique = electrique;
	}
}
							

Voilà, nos deux classes filles héritent de Vehicule et de ses propriétés et implémentent leurs propres propriétés spécifiques. Et pour la méthode affiche alors ? Il faut personnaliser l'affichage de nos classes Voiture et Velo ! Comment faire ? Et bien là encore on utilisera le mot-clé super pour appeler la méthode affiche de la classe mère, et on ajoutera le code spécifique aux classes filles.


class Voiture extends Vehicule{
// La classe Voiture hérite de la classe Vehicule
	constructor(marque, modele, couleur, prix, motorisation, autoradio) {
		super(marque, modele, couleur, prix); // On appelle le constructeur de la classe mère
		this.motorisation = motorisation; 	  // On initialise les propriétés spécifiques à Voiture
		this.possedeAutoradio = autoradio;
	}

	affiche() {
		// La méthode affiche écrit la description de la voiture dans le document HTML.
		super.affiche(); // On appelle la méthode affiche de la classe mère 
		document.write("
Motorisation : " + this.motorisation); //On ajoute les propriétés spécifiques à Voiture if (this.possedeAutoradio) document.write("
Autoradio : oui"); else document.write("
Autoradio : non"); } } class Velo extends Vehicule{ // La classe Velo hérite de la classe Vehicule constructor(marque, modele, couleur, prix, type, electrique) { super(marque, modele, couleur, prix); // On appelle le constructeur de la classe mère this.type = type; // On initialise les propriétés spécifiques à Velo this.estElectrique = electrique; } affiche() { // La méthode affiche écrit la description du vélo dans le document HTML. super.affiche(); // On appelle la méthode affiche de la classe mère document.write("
Type : " + this.type); //On ajoute les propriétés spécifiques à Velo if (this.estElectrique) document.write("
Électrique : oui"); else document.write("
Électrique : non"); } }

Nos classes sont finies, testons maintenant en créant quelques voitures et vélos :


let voiture1 = new Voiture("Toyota", "Yaris", "rouge", "30", "III (3) 100H HYBRID DYNAMIC", true);
voiture1.affiche(); // On affiche la description de voiture1

let velo1 = new Velo("Neomouv", "Montana", "jaune", "8", "urbain", true);
velo1.affiche();	// On affiche la description de velo1

let velo2 = new Velo("B'TWIN", "Rockrider 900", "rouge", "5", "VTT", false);
velo2.affiche();	// On affiche la description de velo2
							

Dans le navigateur, on verra ceci s'afficher :


Toyota Yaris de couleur rouge est à louer pour 30 euros par jour.
Motorisation : III (3) 100H HYBRID DYNAMIC
Autoradio : oui

Neomouv Montana de couleur jaune est à louer pour 8 euros par jour.
Type : urbain
Électrique : oui

B'TWIN Rockrider 900 de couleur rouge est à louer pour 5 euros par jour.
Type : VTT
Électrique : non
							

Voilà le JSFiddle avec le code au complet :

Aller au TP