• Aucun résultat trouvé

Programmation objet

N/A
N/A
Protected

Academic year: 2022

Partager "Programmation objet"

Copied!
20
0
0

Texte intégral

(1)

Polymorphisme Polymorphisme

Département Informatique

Programmation objet

Cours n°11

Le polymorphisme d'héritage

(2)

Polymorphisme Polymorphisme

Département Informatique

Le Polymorphisme des classes

Une instance d ’une classe dérivée contient en interne une instance de sa classe de base.

On peut donc considérer qu ’une instance de la classe dérivée peut être utilisée à la place

d ’une instance de la classe de base.

Une instance d ’une classe dérivée F de M peut être vue sous deux formes :

•L ’instance est du type F

•L ’instance est du type M

On appelle ceci du polymorphisme.

(3)

Polymorphisme Polymorphisme

Département Informatique

Exemple :

Class M {}; class F:public M {};

void fonc(M&);

M m1;

F f1;

fonc(m1); // ok, m1 est du type M fonc(f1); // ok, f1 est du type F dérivé de M L ’instance f1 est vue ici comme étant de type M.

Bien entendu, les propriétés spécifiques de f1 ne peuvent pas être utilisées par fonc.

(4)

Polymorphisme Polymorphisme

Département Informatique La conversion de f1 en un objet de type M est donc ici implicite.

Elle est décidée par le compilateur dès la

compilation et pour toute la durée du programme.

On parle donc ici de polymorphisme statique.

Le polymorphisme fonctionne uniquement dans un seul sens :

• Une instance de la classe dérivée peut remplacer une instance de la classe de base

• Un pointeur (ou une référence) sur une instance de la classe dérivée peut remplacer un pointeur

(référence) sur une instance de la classe de base.

Mais pas le contraire !

(5)

Polymorphisme Polymorphisme

Département Informatique Les limites du polymorphisme statique

Considérons l ’exemple suivant :

#include <iostream>

using namespace std;

class M {

int a;

public:

M(int a1=0) : a(a1) {};

int get_a()

{ cout << "M::get_a() \n";

return a;}

};

(6)

Polymorphisme Polymorphisme

Département Informatique

class F : public M {

int a;

public :

F(int a1=0) : a(a1) {};

//--- appel automatique à M() int get_a()

{ cout << "F::get_a() \n";

return a;}

};

void f(M &m) { cout << m.get_a()

<< '\n';}

(7)

Polymorphisme Polymorphisme

Département Informatique

void main() { M m1(3);

F f1(4);

f(m1);

f(f1);

cout<<f1.get_a();

}

Le programme affichera : M::get_a() 3 M::get_a() 0 F::get_a() 4 car l’appel de f(f1) exécute la méthode M::get_a() et f1.M::a=0, alors que la dernière ligne emploie F : :get_a() et que f1.a=4

(8)

Polymorphisme Polymorphisme

Département Informatique

On voit qu ’un problème se pose :

Le compilateur décidant que f1 est du type M pour l ’appel de la fonction, c ’est à chaque fois M::get_a() qui est appelée, alors que

get_a a été redéfinie dans F.

C ’est très gênant, puisqu ’on perd

l ’intérêt de pouvoir spécialiser une classe dérivée.

Il faudrait que, lors de l ’exécution de f(), le

compilateur choisisse quelle est la méthode get_a à appeler en fonction du type réel de l ’instance utilisée.

(9)

Polymorphisme Polymorphisme

Département Informatique

Polymorphisme dynamique

Dans ce cas, le compilateur ne décide du type réel de l ’instance (dérivée ou base) que lors de l ’exécution.

Pour que ceci soit possible, la méthode doit être déclarée comme étant virtuelle (mot-clé

virtual)

Si l ’on reprend l ’exemple précédent, en indiquant que M::get_a est

virtuelle :

virtual int get_a { //.. Code identique }

(10)

Polymorphisme Polymorphisme

Département Informatique

void main() { M m1(3);

F f1(4);

f(m1);

f(f1);

cout<<f1.get_a();

}

Le programme affichera : M::get_a() 3 F::get_a() 4 F::get_a() 4 La bonne fonction est appelée, grâce à son statut virtuel.

(11)

Polymorphisme Polymorphisme

Département Informatique

ATTENTION :

Une propriété membre d’une classe ne peut pas être virtuelle.

Un membre statique d’une classe ne peut pas être virtuel.

Les constructeurs ne peuvent pas être virtuels

Les destructeurs peuvent être définis virtuels.

Quand on utilise une fonction globale, l’effet virtuel n’est plus appliqué lorsque le paramètre est passé par valeur

Le statut virtuel est conservé par l ’héritage.

Une fonction virtuelle peut être redéfinie : elle reste virtuelle

Une fonction virtuelle peut être surchargée : elle perd son statut virtuel puisqu'il s'agit d'une autre fonction.

(12)

Polymorphisme Polymorphisme

Département Informatique

Classes abstraites

Dans une hiérarchie d ’héritage, il est fréquent que les classes de bases ne soient jamais instanciées.

Elles fournissent alors uniquement un canevas pour le développement de classes dérivées.

On parle pour de telles classes de base de classes abstraites.

On ne peut pas construire d ’instances d ’une classe abstraite. Cela n'aurait d'ailleurs pas de sens.

(13)

Polymorphisme Polymorphisme

Département Informatique

Exemple : définition de formes géométriques Toutes les formes possèdent des propriétés

communes. (ex : origine)

Toutes les formes géométriques possèdent une surface, mais son expression ne peut pas être

généralisée.

Il est donc intéressant de définir une classe abstraite FORME et de dériver des classes

RECTANGLE, CERCLE, etc...

Il est en effet inutile de créer un objet de type FORME.

(14)

Polymorphisme Polymorphisme

Département Informatique

En C++, une classe est abstraite si elle contient au moins une fonction virtuelle pure.

Une fonction virtuelle pure est virtuelle, mais ne contient aucun code. Elle ne peut donc pas être appelée directement, mais doit être redéfinie dans

les classes dérivées.

La syntaxe est :

virtual <retour> fonc(<params>) = 0;

Si la fonction n ’est pas redéfinie dans la classe dérivée, celle-ci reste abstraite. Elle n'est donc

pas instanciable.

(15)

Polymorphisme Polymorphisme

Département Informatique

Exemple utilisation polymorphisme

Nous allons écrire les classes permettant de gérer des personnes.

Toutes les personnes gérées sont des humains.

Certaines sont des hommes, d ’autres des femmes.

Soit la hiérarchie de classes suivante : Hu

Ho Fe

(16)

Polymorphisme Polymorphisme

Département Informatique

class Humain {

private:

std::string Nom,Prenom;

//….

public:

Humain(std::string n,std::string p):

Nom(n),Prenom(p){};

virtual std::string DonneGenre() const =0;

void Affiche();

};

La classe contenant une fonction virtuelle pure, elle est abstraite.

(17)

Polymorphisme Polymorphisme

Département Informatiqueclass Femme:public Humain {

public:

std::string DonneGenre() const { return "Féminin";}

Femme(std::string n,std::string p) :Humain(n,p){}

class Homme:public Humain};

{

public:

std::string DonneGenre() const { return "Masculin";}

Homme(std::string n,std::string p) :Humain(n,p);

}; Ces deux classes définissent la méthode DonneGenre : elles ne sont pas abstraites.

(18)

Polymorphisme Polymorphisme

Département Informatique

La méthode Humain::Affiche n ’a pas besoin d ’être redéfinie dans les classes dérivées.

void Humain::Affiche() {

cout<<Nom<<Prenom;

}

Cette méthode pourra être utilisée avec Femme ou Homme. Si l ’on désire la redéfinir, il faudra appeler

Humain::Affiche() pour l ’affichage de Nom et Prenom

(19)

Polymorphisme Polymorphisme

Département Informatiquevoid main() {

Homme HD(« Henri »,  « Dupont »);

Femme FD(« Francine », « Durand »);

Humain *pH;

cout<<HD.DonneGenre();

cout<<FD.DonneGenre();

pH = &HD;

cout<<pH->DonneGenre();

pH->Affiche();

pH = &FD;

cout<<pH->DonneGenre();

pH->Affiche();

}

(20)

Polymorphisme Polymorphisme

Département Informatique

Prochain cours : Notion d'interface

A la semaine prochaine !

Références

Documents relatifs

• On peut imaginer que le projet permette à Sofiane de s’approprier les notions en lien avec sa question de grand oral :. o Critères de choix

Dans ma préface, j'imagine que Marianne s'adresse à moi, mais pas à moi en tant que Henri Pena-Ruiz, mais à tous les citoyens, à toutes les citoyennes qu'elle unit, non

Christian Poslaniec : On dirait que tu as abandonné Pierrot et Colombine, ainsi que l'encre, en même temps que fermait l'atelier du vieux Mans.. On commence par

Aussi si vous avez choisi de venir ici pour aider l’humanité, pour remplir votre mission d’éveil de conscience tout autour de vous, chacun et chacune à votre

Il est question à travers cette étude de faire un diaporama de la gouvernance de la forêt Boucher dans la ville de Gatineau, en s’intéressant particulièrement

Résultats : vitesse au dernier palier complété Tests Triangulaires.. ➢ Il existe deux protocoles

[r]

On