- Une classe mère peut servir à regrouper des méthodes communes à un certain nombre de classes filles, sans pouvoir fournir une implémentation générale de ces méthodes.
- Les méthodes déclarées mais non implémentées dans la classe mère sont déclarées virtuelles pures, grâce à =0;
- Une classe qui contient au moins une méthode virtuelle pure est appelée classe abstraite. Elle ne peut pas être instanciée directement. Elle doit d’abord être dérivée en une classe fille qui redéfinit les méthodes virtuelles pures.
- Une classe abstraite définit une “interface”. Toutes les classes filles héritent seulement des noms des méthodes et non pas de leur implémentation.
class Animal{
public :
virtual void affiche() const = 0;
};
class Chien: public Animal{
public :
virtual void affiche() const {
cout << "Je suis un chien." << endl;
}
};
class Chat: public Animal{
public :
virtual void affiche() const {
cout << "Je suis un chat." << endl;
}
};
Animal unAnimal; // ERREUR ! on ne peut pas créer un objet de type Animal
Animal * unAnimal = new Chien();
unAnimal->affiche (); // OK affiche : " Je suis un chien."-
On peut résumer les fonctions virtuelles de la manière suivante :
- Une méthode virtuelle peut être redéfinie dans une classe fille.
- Une méthode virtuelle pure doit être redéfinie dans une classe fille
-
Le polymorphisme permet de regrouper des variables de types différents (différentes classes filles) dans un même conteneur en utilisant des pointeurs sur la classe mère.
-
Le fait d’avoir des fonctions virtuelles permet d’appeler les méthodes de la classe fille à partir du pointeur sur la classe mère, quelle que soit le type d’objet fille stocké dans le conteneur.
std::vector<Animal *> listeAnimaux;
listeAnimaux.push_back(new Chien());
listeAnimaux.push_back(new Chat());
listeAnimaux[0]->affiche(); // affiche "Je suis en chien."
listeAnimaux[1]->affiche(); // affiche "Je suis un chat."- Attention, il faut penser à supprimer les objets avec delete lorsque l’on utilise un vecteur de pointeur
- Le polymorphisme est une notion extrêmement puissante et agréable : elle permet à l’exécution d’un programme de gérer de la même façon des types différents et de leur appliquer des traitements spécifiques. Bien sûr cela a un coût et peut ralentir sensiblement l’exécution du programme si les appels aux fonctions virtuelles sont très nombreux.
- Dès que l’on déclare une fonction virtuelle dans une classe, le compilateur implémente (de façon transparente) une table de pointeurs de fonctions afin de pouvoir décider à l’exécution quelle méthode appeler.