Plan de ce chapitre: Introduction
Utilisation pratique
Exemple Delphi
Exercice 3 classes
Polymorphisme (autres chapitres) : par implémentation d'interfaces
Les classes abstraites permettent de créer des classes génériques expliquant certains comportements sans les implémenter et fournissant une implémentation commune de certains autres comportements pour l'héritage de classes. Les classes abstraites sont un outil intéressant pour le polymorphisme.
- Une classe abstraite est une classe qui ne peut pas être instanciée.
- Une classe abstraite peut contenir des méthodes déjà implémentées.
- Une classe abstraite peut contenir des méthodes non implémentées.
- Une classe abstraite est héritable.
- On peut contsruire une hiérarchie de classes abstraites.
- Pour pouvoir construire un objet à partir d'une classe abstraite, il faut dériver une classe non abstraite en une classe implémentant toutes les méthodes non implémentées.
Une méthode déclarée dans une classe, non implémentée dans cette classe, mais juste définie par la déclaration de sa signature, est dénommée méthode abstraite. Une méthode abstraite est une méthode à liaison dynamique n’ayant pas d’implémentation dans la classe où elle est déclarée. L' implémentation d'une méthode abstraite est déléguée à une classe dérivée.
Si vous voulez utiliser la notion de classe abstraite pour fournir un polymorphisme à un groupe de classes, elles doivent toutes hériter de cette classe, comme dans l'exemple ci-dessous :
- La classe Véhicule est abstraite, car la méthode Démarrer est abstraite et sert de "modèle" aux futurs classes dérivant de Véhicule, c'est dans les classes voiture, voilier et croiseur que l'on implémente le comportement précis du genre de démarrage.
- Notons au passage que dans la hiérarchie précédente, les classes vehicule Terrestre et Marin héritent de la classe Véhicule, mais n'implémentent pas la méthode abstraite Démarrer, ce sont donc par construction des classes abstraites elles aussi.
Les classes abstraites peuvent également contenir des membres déjà implémentés. Dans cette éventualité, une classe abstraite propose un certain nombre de fonctionnalités identiques pour tous ses futurs descendants.(ceci n'est pas possible avec une interface). Exemple la classe abstraite Véhicule n'implémentent pas la méthode abstraite Démarrer, mais fournit et implante une méthode "RépartirPassagers" de répartition des passagers à bord du véhicule (fonction de la forme, du nombre de places, du personnel chargé de s'occuper de faire fonctionner le véhicule...), elle fournit aussi et implante une méthode "PériodicitéMaintenance" renvoyant la périodicité de la maintenance obligatoire du véhicule (fonction du nombre de km ou miles parcourus, du nombre d'heures d'activités,...)
Ce qui signifie que toutes les classes voiture, voilier et croiseur savent comment répartir leur éventuels passagers et quand effectuer une maintenance, chacune d'elle implémente son propre comportement de démarrage.
Syntaxe de l'exemple en Delphi et en Java (C# est semblable à Delphi) :
Delphi Java Vehicule = class
public
procedure Demarrer; virtual;abstract;
procedure RépartirPassagers; virtual;
procedure PériodicitéMaintenance; virtual;
end;abstract class ClasseA { public abstract void Demarrer( );
public void RépartirPassagers( );
public void PériodicitéMaintenance( );
}
Utilisation pratique des classes abstraites
- Utilisez une classe abstraite lorsque vous voulez :
- d'une part regrouper un ensemble de méthodes présentant des fonctionnalités identiques,
- et aussi d'autre part vous souhaitez disposer de facilités dans la déclaration et l'implémentation de nouvelles méthodes.
- Lorsque l'on élabore des composants réutilisables, les classes abstraites sont très utiles pour anticiper les adjonctions ultérieures. Dans le cas de nouvelles versions, la classe abstraite de base est aisément extensible, les logiciels écrit pour la version précédente de la classe fonctionneront toujours avec les anciens membres.
Exemple de code Delphi pour la hiérarchie ci-dessous :
Soit en Delphi l'écriture d'un exemple tiré de cette hiérarchie :
Delphi Unit UclassVehicules; interface
Vehicule = class
public
procedure Demarrer; virtual;abstract;
procedure RépartirPassagers; virtual;
procedure PériodicitéMaintenance; virtual;
end;Terrestre = class ( Vehicule )
public
procedure PériodicitéMaintenance; override;
end;Voiture = class ( Terrestre )
public
procedure Demarrer; override;
procedure RépartirPassagers; override;
end;Marin = class ( Vehicule )
public
procedure PériodicitéMaintenance; override;
end;Voilier = class ( Marin )
public
procedure Demarrer; override;
procedure RépartirPassagers; override;
end;Croiseur = class ( Marin )
public
procedure Demarrer; override;
procedure RépartirPassagers; override;
end;implementation
//---> les méthodes implantées de la classe abstraite Vehicule :
procedure Vehicule.RépartirPassagers;
begin
..........
end;procedure Vehicule.PériodicitéMaintenance;
begin
..........
end;//---> les méthodes implantées de la classe abstraite Terrestre :
procedure Terrestre.PériodicitéMaintenance;
begin
..........
end;//---> les méthodes implantées de la classe abstraite Marin :
procedure Marin.PériodicitéMaintenance;
begin
..........
end;//---> les méthodes implantées de la classe Voiture :
procedure Voiture.Demarrer;
begin
..........
end;
procedure Voiture.RépartirPassagers;
begin
..........
end;
//---> les méthodes implantées de la classe Voilier :
procedure Voilier.Demarrer;
begin
..........
end;
procedure Voilier.RépartirPassagers;
begin
..........
end;
//---> les méthodes implantées de la classe Croiseur :
procedure Croiseur.Demarrer;
begin
..........
end;
procedure Croiseur.RépartirPassagers;
begin
..........
end;
Dans cet exemple :
- Les classes Vehicule, Marin et Terrestre sont abstraites car aucune n'implémente la méthode abstraite Demarrer.
- Les classes Marin et Terrestre contiennent chacune une surcharge dynamique implémentée de la méthode virtuelle PériodicitéMaintenance qui est déjà implémentée dans la classe Véhicule.
- Les classes Voiture, Voilier et Croiseur ne sont pas abstraites car elles implémentent les (la) méthodes abstraites de leurs parents.