SlideShare ist ein Scribd-Unternehmen logo
1 von 107
Downloaden Sie, um offline zu lesen
Zineb Dafir
Z.Dafir@emsi.ma
01/04/2023 Z.Dafir@emsi.ma 1
Plan
Généralités
Classe Dérivée
Mode de dérivation
01/04/2023 Z.Dafir@emsi.ma 2
Redéfinition des méthodes dans la
classe dérivée
Constructeurs Destructeurs
Héritage et Amitié
L’héritage et la surcharge des opérateurs
Généralités
 L'héritage est le troisième des
paradigmes de la programmation
orientée objet.
 Il est basé sur le principe de
réutilisation:
 Créer une nouvelle classe à partir d’une classe
existante.
 Ajouter des fonctionnalités à partir d’une
classe existante.
01/04/2023 Z.Dafir@emsi.ma 3
Généralités
"Il est plus facile
"Il est plus facile
de modifier que
de réinventer"
01/04/2023 Z.Dafir@emsi.ma 4
Généralités
 L'héritage peut être simple ou multiple.
 L'héritage est mis en œuvre par la
construction de classes dérivées.
01/04/2023 Z.Dafir@emsi.ma 5
Généralités
Classe A
01/04/2023 Z.Dafir@emsi.ma 6
Classe B
Généralités
Classe A Classe B
Classe de Classe
01/04/2023 Z.Dafir@emsi.ma 7
Classe de
base
Classe
Dérivée
A est la classe de base ou classe mère ou super-classe.
B est la nouvelle classe qui hérite de la classe existante A.[
Classe fille ou classe dérivée ou sous-classe].
Génralités
 L'héritage représente la relation EST-UN:
 Un chat est un animal.
 Une moto est un véhicule.
 Un cercle est une forme.
01/04/2023 Z.Dafir@emsi.ma 8
Généralités
Animal
01/04/2023 Z.Dafir@emsi.ma 9
Oiseau
Chat Chien
La classe animal est la classe de base (classe supérieure).
Les classes chat, chien et oiseau sont des classes
dérivées (sous-classes).
Généralités
Vehicule
01/04/2023 Z.Dafir@emsi.ma 10
Moto
Avion Voiture
De course Décapotable
Héritage Définition
01/04/2023 Z.Dafir@emsi.ma 11
Une Classe Dérivée
La nouvelle classe (ou classe dérivée ou
sous classe) hérite de tous les membres,
sous classe) hérite de tous les membres,
qui ne sont pas privés, de la classe de base
et ainsi réutilise le code déjà écrit pour la
classe de base.
01/04/2023 Z.Dafir@emsi.ma 12
Une Classe Dérivée
 Une classe dérivée modélise un cas particulier
de la classe de base et, est donc enrichie
d'informations supplémentaires.
 La classe dérivée possède les propriétés
suivantes:
Hérite les méthodes et les attributs de la classe de
base.
Peut en posséder de nouvelles méthodes
(enrichissement)
Peut redéfinir certaines méthodes.(spécialisation)
01/04/2023 Z.Dafir@emsi.ma 13
Syntaxe de l’héritage
 class classe_dérivée:protection classe_de_base
{/* etc. */}
 Les types de protections sont :public ,
protected , private.
01/04/2023 Z.Dafir@emsi.ma 14
Syntaxe de l’héritage (exemple)
 La classe B hérite de façon publique de la classe A.
 Tous les membres publics ou protégés de la classe
A font partis de l’interface de la classe B.
01/04/2023 Z.Dafir@emsi.ma 15
Les droits d’accès en C++
01/04/2023 Z.Dafir@emsi.ma 16
Mode de derivation
 Lors de la définition de la classe dérivée
il est possible de spécifier le mode de
dérivation par l’emploi d’un des
mots−clé suivants : public, protected ou
mots−clé suivants : public, protected ou
private.
 Ce mode de dérivation détermine quels
membres de la classe de base sont
accessibles dans la classe dérivée.
01/04/2023 Z.Dafir@emsi.ma 17
Mode de derivation
 Au cas où aucun mode de dérivation
n’est spécifié, le compilateur C++
prend par défaut le mot−clé private
pour une classe.
 Les membres privés de la classe de
base ne sont jamais accessibles par les
membres des classes dérivées.
01/04/2023 Z.Dafir@emsi.ma 18
Mode de derivation Résumé
01/04/2023 Z.Dafir@emsi.ma 19
Heritage Public
 Il donne aux membres publics et
protégés de la classe de base le même
statut dans la classe dérivée.
 C’est la forme la plus courante
d’héritage, car il permet de modéliser
les relations "Y est une sorte de X" ou
"Y est une spécialisation de la classe de
base X".
01/04/2023 Z.Dafir@emsi.ma 20
Heritage Public (Exemple)
class Vehicule {
public:
void pub1();
protected:
void prot1();
private:
void priv1();
};
class Voiture : public Vehicule {
class Voiture : public Vehicule {
public:
int pub2() {
pub1(); // OK
prot1(); // OK
priv1(); // ERREUR
}
};
Voiture v;
v.pub1(); // OK
v.pub2(); // OK
01/04/2023 Z.Dafir@emsi.ma 21
Heritage Privé
 Il donne aux membres publics et
protégés de la classe de base le statut
de membres privés dans la classe
dérivée.
 Il permet de modéliser les relations "Y
 Il permet de modéliser les relations "Y
est composé de un ou plusieurs X".
 Plutôt que d’hériter de façon privée de
la classe de base X, on peut faire de la
classe de base une donnée membre
(composition).
01/04/2023 Z.Dafir@emsi.ma 22
Heritage Privé (Exemple)
class String {
public:
int length();
// ...
};
class Telephone_number : private String {
class Telephone_number : private String {
void f1() {
// ...
l = length(); // OK
};
Telephone_number tn;
cout << tn.length(); // ERREUR
01/04/2023 Z.Dafir@emsi.ma 23
Heritage Protégé
 Il donne aux membres publics et
protégés de la classe de base le statut
de membres protégés dans la classe
dérivée.
 L’héritage fait partie de l’interface mais
n’est pas accessible aux utilisateurs.
01/04/2023 Z.Dafir@emsi.ma 24
Heritage Protégé (Exemple)
class String {
protected:
int n;
};
class Telephone_number : protected String {
protected:
protected:
void f2() { n++; } // OK
};
class Local_number : public Telephone_number {
protected:
void f3() { n++; } // OK
};
01/04/2023 Z.Dafir@emsi.ma 25
Mode de derivation Résumé
01/04/2023 Z.Dafir@emsi.ma 26
Redéfinition des méthodes dans la
classe dérivée
On peut redéfinir une fonction dans
une classe dérivée si on lui donne le
une classe dérivée si on lui donne le
même nom que dans la classe de base.
01/04/2023 Z.Dafir@emsi.ma 27
Redéfinition des méthodes dans la
classe dérivée
01/04/2023 Z.Dafir@emsi.ma 28
Redéfinition des méthodes dans la
classe dérivée
01/04/2023 Z.Dafir@emsi.ma 29
Redéfinition des méthodes dans la
classe dérivée
01/04/2023 Z.Dafir@emsi.ma 30
Redéfinition des méthodes dans la
classe dérivée
01/04/2023 Z.Dafir@emsi.ma 31
AJUSTEMENT d’accès
 Lors d’un héritage protégé ou privé, nous
pouvons spécifier que certains membres de
la classe mère conservent leur mode d’accès
la classe mère conservent leur mode d’accès
dans la classe dérivée.
 Ce mécanisme, appelé déclaration d’accès,
ne permet en aucun cas d’augmenter ou de
diminuer la visibilité d’un membre de la
classe de base.
01/04/2023 Z.Dafir@emsi.ma 32
L’héritage: les constructeurs
 Les constructeurs par défaut des classes de
bases sont automatiquement appelés avant le
constructeur de la classe dérivée.
constructeur de la classe dérivée.
01/04/2023 Z.Dafir@emsi.ma 33
L’héritage: les constructeurs
 Lors de l’instanciation d’une classe dérivée, il faut
initialiser:
Les attributs propres à la classe dérivée.
Les attributs hérités de la classe mère.
Les attributs hérités de la classe mère.
Mais il ne doit pas être à la charge du concepteur
de la classe dérivée de réaliser lui-même
l’initialisation des attributs hérités.
01/04/2023 Z.Dafir@emsi.ma 34
L’héritage: les constructeurs
 L’accès à ces attributs pourrait être interdit!
(private).
 L’initialisation des attributs hérités doit donc se
faire au niveau de la classe où ils sont
faire au niveau de la classe où ils sont
explicitement définis.
 Solution: L’initialisation des attributs hérités doit
se faire en invoquant les constructeurs de la classe
mère.
01/04/2023 Z.Dafir@emsi.ma 35
L’héritage et les constructeurs
 L’invocation du constructeur de la classe
mère se fait au début de la section d’appel
aux constructeurs des attributs.
aux constructeurs des attributs.
01/04/2023 Z.Dafir@emsi.ma 36
L’héritage: les constructeurs
 Lorsque la classe mère admet un
constructeur par défaut, l’invocation
explicite de ce constructeur dans la classe
explicite de ce constructeur dans la classe
dérivée n’est pas obligatoire.
 Le compilateur se charge de réaliser
l’invocation du constructeur par défaut.
01/04/2023 Z.Dafir@emsi.ma 37
L’héritage: les constructeurs
 Si la classe mère n’admet pas de
constructeur par défaut, l’invocation
explicite d’un de ses constructeurs est
explicite d’un de ses constructeurs est
obligatoire dans le constructeur de la classe
dérivée.
 La classe dérivée doit admettre au moins un
constructeur explicite.
01/04/2023 Z.Dafir@emsi.ma 38
L’héritage: les constructeurs
01/04/2023 Z.Dafir@emsi.ma 39
Héritage des
constructeurs/destructeurs
01/04/2023 Z.Dafir@emsi.ma 40
L’héritage: les constructeurs
01/04/2023 Z.Dafir@emsi.ma 41
L’héritage: les constructeurs
01/04/2023 Z.Dafir@emsi.ma 42
L’héritage: les constructeurs
Exemple de la classe véhicule
01/04/2023 Z.Dafir@emsi.ma 43
L’héritage: les constructeurs
Exemple de la classe avion
01/04/2023 Z.Dafir@emsi.ma 44
L’héritage: les destructeurs
 L’appel des destructeurs se fera dans l’ordre
inverse des constructeurs.
01/04/2023 Z.Dafir@emsi.ma 45
L’héritage: les destructeurs
Exemple de la classe véhicule et la classe avion
01/04/2023 Z.Dafir@emsi.ma 46
L’héritage: les destructeurs
Exemple de la classe véhicule et la classe avion
 Le destructeur de la classe avion est appelé en premier.
 Il faut d’abord détruire l’avion et le véhicule sera
détruit par la suite.
01/04/2023 Z.Dafir@emsi.ma 47
détruit par la suite.
L’Héritage et la surcharge des
opérateurs
 A l'exception de la fonction d'affectation operator=( ), toutes les
fonctions à opérateurs surchargés d'une classe A sont transmises
par héritage à la classe dérivée B, avec les règles de résolution
standard pour les fonctions surchargées.
 Les fonctions à opérateurs surchargés définis à l’intérieur de la
classe de base(surcharge interne) peuvent être transmises par
héritage à la classe dérivée.
 Les fonctions à opérateurs surchargés définis à l’extérieur de la
classe de base(surcharge externe) ne peuvent pas être appelées
dans la classe dérivée, car elles ne sont pas des fonctions de la
classe de base.
01/04/2023 Z.Dafir@emsi.ma 48
L’Héritage et la surcharge des
opérateurs
01/04/2023 Z.Dafir@emsi.ma 49
L’Héritage et la surcharge des
opérateurs
 Le constructeur de copie et l'opérateur d'affectation
sont les deux manières d'initialiser un objet à l'aide
d'un autre objet.
 La différence fondamentale entre le constructeur de
 La différence fondamentale entre le constructeur de
copie et l'opérateur d'affectation réside dans le fait que
le constructeur de copie alloue une mémoire
distincte aux deux objets, à savoir le nouvel objet cible
créé et l'objet source.
 L' opérateur d'affectation alloue le même
emplacement mémoire au nouvel objet cible ainsi que
objet source.
01/04/2023 Z.Dafir@emsi.ma 50
L’Héritage et la surcharge des
opérateurs -exemple
 La surcharge de l’opérateur d’affectation se fait à l’intérieur
de la classe.
 Exemple :
class vehicule {
double vitesse;
double vitesse;
int nbre_passagers;
public:
vehicule operator=(vehicule const&v){
vitesse= v.vitesse;
nbre_passagers=v.nbre_passagers;
cout<<"vehicule";
return *this;
}};
vehicule v2=v1;//appel du constructeur par copie
v2=v1;//appel à l'opérateur d'affectation
01/04/2023 Z.Dafir@emsi.ma 51
L’Héritage et la surcharge des
opérateurs -exemple
 Avant de redéfinir l’opérateur ‘==‘ pour la classe véhicule, on ne peut pas tester
l’égalité de deux véhicules dans le main par exemple if (v1==v2) cout<< « les
véhicules sont identiques ». Cela n’est pas possible car cet opérateur n’est pas
défini pour l’objet véhicule. Et donc il est nécessaire de redéfinir cet opérateur
pour la classe véhicule.
class vehicule {
class vehicule {
public:
bool operator==(vehicule const &v){
if (vitesse==v.vitesse && nbre_passagers==v.nbre_passagers)return true;
else return false;
}};//fin de la classe véhicule
Maintenant si on fait le test suivant dans le main:
vehicule v1(300,5), v2(300,5);//création de deux objets véhicule
if(v1==v2) cout<<"les mêmes véhicules";//le test avec l’opérateur ==
Cela va nous afficher les mêmes véhicules .
01/04/2023 Z.Dafir@emsi.ma 52
L’Héritage et la surcharge des
opérateurs -exemple
 On peut même tester l’égalité de deux avions si on considère la classe avion qui
hérite de la classe véhicule :
class avion:public vehicule {
int nbre_moteurs;
….
….
};
• Après avoir redéfini l’opérateur ‘==‘ pour la classe véhicule qui est la classe de base,
on peut tester l’égalité de deux avions, en faisant dans le main par exemple :
• if(a1==a2) cout<<"les mêmes avions";//le test avec l’opérateur == de la classe
véhicule .
• Mais ce test ne va pas inclure le nombre de moteurs qui est un attribut propre à la
classe dérivée (avion). Si on veut tester l’égalité des deux avions en incluant l’attribut
qui est propre à la classe avion, il faut redéfinir cet opérateur pour la classe avion.
01/04/2023 Z.Dafir@emsi.ma 53
L’Héritage et la surcharge des
opérateurs -exemple
• Pour redéfinir l’opérateur ‘==‘ pour la classe dérivée on peut appeler celui de la
classe mère (classe véhicule), car la fonction de surcharge de l’opérateur ‘==‘ de
la classe véhicule est défini à l’intérieur de la classe (une fonction de la classe).
bool operator==(avion const &a){
bool operator==(avion const &a){
return (vehicule::operator==(a)&& (nbre_moteurs==a.nbre_moteurs)) ?
true:false;
}
vehicule::operator==(a): appel de la fonction operator== de la classe véhicule qui
est la classe de base.
01/04/2023 Z.Dafir@emsi.ma 54
Récapitulatif
 Une classe dérivée hérite tous les membres de la classe
de base sauf : les constructeurs, le destructeur, et
les opérateurs.
 Les constructeurs ne sont pas hérités directement mais
 Les constructeurs ne sont pas hérités directement mais
sont utilisés dans la liste d’initialisation des
constructeurs de la classe dérivée.
 Le destructeur est utilisé automatiquement à la
destruction de l’objet.
 Les opérateurs doivent être redéfinis par la classe
dérivée en appelant ceux de la classe de base.
01/04/2023 Z.Dafir@emsi.ma 55
Héritage et amitié
L’amitié pour une classe s’hérite, mais
uniquement sur les membres de la classe
hérités, elle ne se propage pas aux nouveaux
hérités, elle ne se propage pas aux nouveaux
membres de la classe dérivée et ne s’étend
pas aux générations suivantes.
01/04/2023 Z.Dafir@emsi.ma 56
Héritage et amitié- Exemple
01/04/2023 Z.Dafir@emsi.ma 57
Héritage et amitié
 L’amitié pour une fonction ne s’hérite pas.
 A chaque dérivation, vous devez redéfinir les
relations d’amitié avec les fonctions.
01/04/2023 Z.Dafir@emsi.ma 58
Récapitulatif
 L'héritage permet de spécialiser une classe.
 Lorsqu'une classe hérite d'une autre classe, elle récupère toutes ses
propriétés et ses méthodes.
 Faire un héritage a du sens si on peut dire que l'objet A "est un"
objet B . Par exemple, une Voiture "est un" Vehicule .
La classe de base est appelée classe mère, et la classe qui en hérite
 La classe de base est appelée classe mère, et la classe qui en hérite
est appelée classe fille.
 Les constructeurs sont appelés dans un ordre bien précis : classe
mère, puis classe fille.
 En plus de public et private , il existe une portée protected ,
équivalente à private mais plus ouverte : les classes filles peuvent
elles aussi accéder aux éléments.
 Si une méthode a le même nom dans la classe fille et la classe mère,
c'est la méthode la plus spécialisée, celle de la classe fille, qui est
appelée.
01/04/2023 Z.Dafir@emsi.ma 59
Zineb Dafir
Z.Dafir@emsi.ma
01/04/2023 Z.Dafir@emsi.ma 60
Plan
Définition
Syntaxe
Constructeurs/destructeurs
01/04/2023 Z.Dafir@emsi.ma 61
Accès aux membres de la super-classe
Définition
• L’héritage multiple est un mécanisme
de programmation orientée objet
dans lequel une classe peut hériter de
comportements et de fonctionnalités de
comportements et de fonctionnalités de
plus d'une super-classe.
• Il s'oppose à l'héritage simple, dans
lequel une classe ne peut hériter que
d'une seule super-classe.
01/04/2023 Z.Dafir@emsi.ma 62
Définition
Classe A2
Classe A1
01/04/2023 Z.Dafir@emsi.ma 63
Classe B
Syntaxe
• class A1 { . . . };
• class A2 { . . . };
class B : [public, protected ou private]
• class B : [public, protected ou private]
A1, [public, ...] A2 { . . . };
01/04/2023 Z.Dafir@emsi.ma 64
Syntaxe générale
• class nomSousClasse : public
nomSuperClasse1, ……………..,
public NomSuperClasseN { …
public NomSuperClasseN { …
};
• L’ordre de déclaration des super-classes
est pris en compte lors de l’invocation
des constructeurs/ destructeurs.
01/04/2023 Z.Dafir@emsi.ma 65
Héritage multiple-
constructeurs/destructeurs
Comme pour l’héritage simple,
l’initialisation des attributs hérités doit
être faite par invocation des
constructeurs des super-classes.
constructeurs des super-classes.
01/04/2023 Z.Dafir@emsi.ma 66
Héritage multiple-
constructeurs/destructeurs
• Syntaxe:
SousClasse (liste de paramètres):
SuperClasse1(arguments1),………………….
,SuperClasseN(argumentsN),atrribut1
(valeur1), ……..,attributk(valeurk)
(valeur1), ……..,attributk(valeurk)
{ }
01/04/2023 Z.Dafir@emsi.ma 67
Héritage multiple-
constructeurs/destructeurs
• Lorsque l’une des super-classes admet
un constructeur par défaut, il n’est pas
nécessaire de l’invoquer explicitement.
• L’exécution des constructeurs des super-
classes se fait selon l’ordre de la
déclaration d’héritage.
01/04/2023 Z.Dafir@emsi.ma 68
Héritage multiple-
constructeurs/destructeurs
 L’ordre des appels des destructeurs des
super-classes est l’inverse de celui des
appels des constructeurs.
01/04/2023 Z.Dafir@emsi.ma 69
Héritage multiple-Accès aux membres
de la super-classe
 Comme dans le cas de l’héritage simple,
une sous classe peut accéder directement
aux attributs et méthodes protégés ou
publics de la super-classe.
publics de la super-classe.
 Que fait-il lorsque les attributs/méthodes
portent le même nom dans plusieurs super-
classes?
01/04/2023 Z.Dafir@emsi.ma 70
Exemple
01/04/2023 Z.Dafir@emsi.ma 71
Exemple
01/04/2023 Z.Dafir@emsi.ma 72
Exemple
01/04/2023 Z.Dafir@emsi.ma 73
Exemple –Solution 1
01/04/2023 Z.Dafir@emsi.ma 74
Exemple –Solution 2
• Une des solutions consiste à lever l’ambigüité en indiquant
explicitement dans la sous classe quelle(s) méthode(s) on
veut invoquer.
01/04/2023 Z.Dafir@emsi.ma 75
Exemple –Solution 3
• La meilleure solution consiste à ajouter dans la sous-classe
une méthode définissant la bonne interprétation de
l’invocation ambigüe.
01/04/2023 Z.Dafir@emsi.ma 76
Zineb Dafir
Z.Dafir@emsi.ma
01/04/2023 Z.Dafir@emsi.ma 77
Plan
Définition
Les types de polymorphisme
La résolution statique des liens
01/04/2023 Z.Dafir@emsi.ma 78
Méthodes virtuelles
Références et pointeurs
La résolution dynamique des
liens
Définition
 Le polymorphisme est un concept de
POO qui fait référence à la capacité d'une
variable, d'une fonction ou d'un objet à
prendre plusieurs formes.
 Dans le cas du polymorphisme, les objets
d'une classe appartenant au même arbre
hiérarchique (hérités d'une classe mère
commune) peuvent avoir des fonctions
portant le même nom, mais ayant des
comportements différents.
01/04/2023 Z.Dafir@emsi.ma 79
Définition
 Un objet polymorphe est un objet
susceptible de prendre plusieurs
formes pendant l’exécution.
 Le polymorphisme est implémenté
en C++ avec les fonctions virtuelles
(virtual) et l’héritage.
01/04/2023 Z.Dafir@emsi.ma 80
Définition
 Le polymorphisme permet de manipuler
des objets d'une classe fille via des
pointeurs ou des références sur une
classe mère.
classe mère.
01/04/2023 Z.Dafir@emsi.ma 81
Définition
 En grec, "poly" signifie "plusieurs" et
"morphe" signifie "forme".
 Le but est donc de créer du code
 Le but est donc de créer du code
fonctionnant de différentes manières selon
le type qui l'utilise.
 Deux concepts sont nécessaires : des
fonctions virtuelles et des pointeurs ou
références sur l'objet.
01/04/2023 Z.Dafir@emsi.ma 82
Types de polymorphisme
Polymorphisme
01/04/2023 Z.Dafir@emsi.ma 83
le polymorphisme au
moment de la
compilation
le polymorphisme au
moment de l'exécution
Types de polymorphisme
 Le polymorphisme au moment de la
compilation (method overloading):
plusieurs fonctions avec la même
signature.
signature.
 Le polymorphisme au moment de
l'exécution (method overriding): la
redéfinition de fonctions.
01/04/2023 Z.Dafir@emsi.ma 84
Types de polymorphisme -exemple
 Le polymorphisme au moment de la
compilation:
int somme(int a, intb){}//somme(1,2)
double somme(double x, double
y){}//somme(0.5,9.6)
double somme(double x, double
y){}//somme(0.5,9.6)
 Le polymorphisme au moment de
l'exécution:
Etudiant e;
e.afficher();// la fonction afficher existe dans la classe
mère Personne et dans la classe fille Etudiant
01/04/2023 Z.Dafir@emsi.ma 85
Polymorphisme - Exemple
class Vehicule
{
public:
void affiche() const; //Affiche une description du Véhicule
protected:
int m_prix; //Chaque véhicule a un prix
};
class Voiture : public Vehicule //Une Voiture EST UN Véhicule
{
public:
public:
void affiche() const;
private:
int m_portes; //Le nombre de portes de la voiture
};
class Moto : public Vehicule //Une Moto EST UN Véhicule
{
public:
void affiche() const;
private:
double m_vitesse; //La vitesse maximale de la moto
};
01/04/2023 Z.Dafir@emsi.ma 86
Polymorphisme - Exemple
Le corps des fonctions affiche des différentes classes:
void Vehicule::affiche() const
{
cout << "Ceci est un vehicule." << endl;
}
void Voiture::affiche() const
{
cout << "Ceci est une voiture." << endl;
}
void Moto::affiche() const
{
cout << "Ceci est une moto." << endl;
}
01/04/2023 Z.Dafir@emsi.ma 87
Polymorphisme - Exemple
 Chaque classe affiche un message
différent.
 La fonction affiche de la classe mère a
 La fonction affiche de la classe mère a
été masqué après la redéfinition de la
fonction dans les classes filles.
01/04/2023 Z.Dafir@emsi.ma 88
Exemple
int main()
{
Vehicule v;
v.affiche(); //Affiche "Ceci est un vehicule."
Moto m;
m.affiche(); //Affiche "Ceci est une moto."
return 0;
}
01/04/2023 Z.Dafir@emsi.ma 89
La résolution statique des liens
void presenter(Vehicule v) //Présente le véhicule passé en argument
{
v.affiche();
}
int main()
{
Vehicule v;
presenter(v);
Moto m;
presenter(m);
return 0;
}
01/04/2023 Z.Dafir@emsi.ma 90
La résolution statique des liens
• Les messages affichés:
Ceci est un vehicule.
Ceci est un vehicule.
• Le message n'est pas correct pour la
moto ! C'est comme si, lors du passage
dans la fonction, la vraie nature de la
moto s'était perdue, et qu'elle était
redevenue un simple véhicule.
01/04/2023 Z.Dafir@emsi.ma 91
La résolution statique des liens
• En termes techniques, on parle
de résolution statique des liens.
• La fonction reçoit un Vehicule , c'est
• La fonction reçoit un Vehicule , c'est
donc toujours la version Vehicule des
méthodes qui sera utilisée.
01/04/2023 Z.Dafir@emsi.ma 92
La résolution statique des liens
• C'est le type de la variable qui détermine
quelle fonction membre appeler, et non
sa vraie nature.
void presenter(Vehicule v) //Présente le
void presenter(Vehicule v) //Présente le
véhicule passé en argument
{
v.affiche();
}
01/04/2023 Z.Dafir@emsi.ma 93
La résolution dynamique des liens
• Le programme utilise la bonne version
des méthodes car il sait si l'objet est de
type mère ou de type fille.
• L’adaptation de la méthode au type de
l’objet exécuté.
01/04/2023 Z.Dafir@emsi.ma 94
La résolution dynamique des liens
• Les méthodes virtuelles et les
références.
• Les méthodes virtuelles et les pointeurs.
• Les méthodes virtuelles et les pointeurs.
01/04/2023 Z.Dafir@emsi.ma 95
Les méthodes virtuelles
• Pour déclarer une méthode virtuelle, il
suffit d'ajouter le mot-clé virtual dans
le prototype de la classe (dans le
fichier .hpp)
fichier .hpp)
01/04/2023 Z.Dafir@emsi.ma 96
Exemple
class Vehicule
{
public:
virtual void affiche() const; //Affiche une description du Véhicule
protected:
int m_prix; //Chaque véhicule a un prix
};
class Voiture : public Vehicule //Une Voiture EST UN Véhicule
{
public:
public:
virtual void affiche() const;
private:
int m_portes; //Le nombre de portes de la voiture
};
class Moto : public Vehicule //Une Moto EST UN Véhicule
{
public:
virtual void affiche() const;
private:
double m_vitesse; //La vitesse maximale de la moto
};
01/04/2023 Z.Dafir@emsi.ma 97
Les méthodes virtuelles
 Il n'est pas nécessaire de
mettre virtual devant les méthodes des
classes filles. Elles sont
automatiquement virtuelles par
automatiquement virtuelles par
héritage.
 Il n'est pas nécessaire que toutes les
méthodes soient virtuelles. Une classe
peut proposer des fonctions "normales"
et d'autres virtuelles.
01/04/2023 Z.Dafir@emsi.ma 98
Les méthodes virtuelles
• Il ne faut pas mettre virtual dans le
fichier .cpp , mais uniquement dans
le .hpp
01/04/2023 Z.Dafir@emsi.ma 99
Les références
void presenter(Vehicule const& v) //Présente le véhicule passé en
argument
{
v.affiche();
}
int main() //Rien n'a changé dans le main()
int main() //Rien n'a changé dans le main()
{
Vehicule v;
presenter(v);
Moto m;
presenter(m);
return 0;
}
01/04/2023 Z.Dafir@emsi.ma 100
Les références
Ceci est un vehicule.
Ceci est une moto.
• Cela marche ! La fonction presenter() a
bien appelé la bonne version de la
bien appelé la bonne version de la
méthode. En utilisant des fonctions
virtuelles ainsi qu'une référence sur
l'objet, la fonction presenter() a pu
correctement choisir la méthode à
appeler.
01/04/2023 Z.Dafir@emsi.ma 101
Les pointeurs
Vehicule *v;
v=new Vehicule();
v->affiche();
Voiture vt;
Moto m;
Moto m;
v=&vt;
v->affiche();//
v=&m;
v->affiche();//le même pointeur la même
fonction mais la sortie est différente
01/04/2023 Z.Dafir@emsi.ma 102
Les pointeurs
Ceci est un vehicule.
Ceci est une voiture.
Ceci est une moto.
01/04/2023 Z.Dafir@emsi.ma 103
Les pointeurs
void presenter(Vehicule *v){ v->affiche()
;}
Vehicule *v;
Voiture vt;
Voiture vt;
Moto m;
v=&vt;
presenter(v);
v=&m;
presenter(v);//le même pointeur
01/04/2023 Z.Dafir@emsi.ma 104
Les pointeurs
Ceci est une voiture.
Ceci est une moto.
01/04/2023 Z.Dafir@emsi.ma 105
Récapitulatif
 Le polymorphisme représente la
capacité du système à choisir
dynamiquement la méthode qui
correspond au type de l’objet en cours de
correspond au type de l’objet en cours de
manipulation.
 Le polymorphisme est implémenté
en C++ avec les fonctions virtuelles
(virtual), les pointeurs ou les
références.
01/04/2023 Z.Dafir@emsi.ma 106
Zineb Dafir
01/04/2023 Z.Dafir@emsi.ma 107

Weitere ähnliche Inhalte

Ähnlich wie Heritage+polymorphisme.pdf

Ch4HeritageSMI2015_2016.pptx
Ch4HeritageSMI2015_2016.pptxCh4HeritageSMI2015_2016.pptx
Ch4HeritageSMI2015_2016.pptxRihabBENLAMINE
 
Correction Examen 2016-2017 POO .pdf
Correction Examen 2016-2017 POO .pdfCorrection Examen 2016-2017 POO .pdf
Correction Examen 2016-2017 POO .pdfslimyaich3
 
S2-02-PHP-objet.pptx
S2-02-PHP-objet.pptxS2-02-PHP-objet.pptx
S2-02-PHP-objet.pptxkohay75604
 

Ähnlich wie Heritage+polymorphisme.pdf (6)

Ch4HeritageSMI2015_2016.pptx
Ch4HeritageSMI2015_2016.pptxCh4HeritageSMI2015_2016.pptx
Ch4HeritageSMI2015_2016.pptx
 
POO-JAVA-partie-1.pdf
POO-JAVA-partie-1.pdfPOO-JAVA-partie-1.pdf
POO-JAVA-partie-1.pdf
 
Correction Examen 2016-2017 POO .pdf
Correction Examen 2016-2017 POO .pdfCorrection Examen 2016-2017 POO .pdf
Correction Examen 2016-2017 POO .pdf
 
Cours5-heritage.pptx
Cours5-heritage.pptxCours5-heritage.pptx
Cours5-heritage.pptx
 
Chapitre3 2013 POO
Chapitre3 2013 POOChapitre3 2013 POO
Chapitre3 2013 POO
 
S2-02-PHP-objet.pptx
S2-02-PHP-objet.pptxS2-02-PHP-objet.pptx
S2-02-PHP-objet.pptx
 

Heritage+polymorphisme.pdf

  • 2. Plan Généralités Classe Dérivée Mode de dérivation 01/04/2023 Z.Dafir@emsi.ma 2 Redéfinition des méthodes dans la classe dérivée Constructeurs Destructeurs Héritage et Amitié L’héritage et la surcharge des opérateurs
  • 3. Généralités  L'héritage est le troisième des paradigmes de la programmation orientée objet.  Il est basé sur le principe de réutilisation:  Créer une nouvelle classe à partir d’une classe existante.  Ajouter des fonctionnalités à partir d’une classe existante. 01/04/2023 Z.Dafir@emsi.ma 3
  • 4. Généralités "Il est plus facile "Il est plus facile de modifier que de réinventer" 01/04/2023 Z.Dafir@emsi.ma 4
  • 5. Généralités  L'héritage peut être simple ou multiple.  L'héritage est mis en œuvre par la construction de classes dérivées. 01/04/2023 Z.Dafir@emsi.ma 5
  • 7. Généralités Classe A Classe B Classe de Classe 01/04/2023 Z.Dafir@emsi.ma 7 Classe de base Classe Dérivée A est la classe de base ou classe mère ou super-classe. B est la nouvelle classe qui hérite de la classe existante A.[ Classe fille ou classe dérivée ou sous-classe].
  • 8. Génralités  L'héritage représente la relation EST-UN:  Un chat est un animal.  Une moto est un véhicule.  Un cercle est une forme. 01/04/2023 Z.Dafir@emsi.ma 8
  • 9. Généralités Animal 01/04/2023 Z.Dafir@emsi.ma 9 Oiseau Chat Chien La classe animal est la classe de base (classe supérieure). Les classes chat, chien et oiseau sont des classes dérivées (sous-classes).
  • 12. Une Classe Dérivée La nouvelle classe (ou classe dérivée ou sous classe) hérite de tous les membres, sous classe) hérite de tous les membres, qui ne sont pas privés, de la classe de base et ainsi réutilise le code déjà écrit pour la classe de base. 01/04/2023 Z.Dafir@emsi.ma 12
  • 13. Une Classe Dérivée  Une classe dérivée modélise un cas particulier de la classe de base et, est donc enrichie d'informations supplémentaires.  La classe dérivée possède les propriétés suivantes: Hérite les méthodes et les attributs de la classe de base. Peut en posséder de nouvelles méthodes (enrichissement) Peut redéfinir certaines méthodes.(spécialisation) 01/04/2023 Z.Dafir@emsi.ma 13
  • 14. Syntaxe de l’héritage  class classe_dérivée:protection classe_de_base {/* etc. */}  Les types de protections sont :public , protected , private. 01/04/2023 Z.Dafir@emsi.ma 14
  • 15. Syntaxe de l’héritage (exemple)  La classe B hérite de façon publique de la classe A.  Tous les membres publics ou protégés de la classe A font partis de l’interface de la classe B. 01/04/2023 Z.Dafir@emsi.ma 15
  • 16. Les droits d’accès en C++ 01/04/2023 Z.Dafir@emsi.ma 16
  • 17. Mode de derivation  Lors de la définition de la classe dérivée il est possible de spécifier le mode de dérivation par l’emploi d’un des mots−clé suivants : public, protected ou mots−clé suivants : public, protected ou private.  Ce mode de dérivation détermine quels membres de la classe de base sont accessibles dans la classe dérivée. 01/04/2023 Z.Dafir@emsi.ma 17
  • 18. Mode de derivation  Au cas où aucun mode de dérivation n’est spécifié, le compilateur C++ prend par défaut le mot−clé private pour une classe.  Les membres privés de la classe de base ne sont jamais accessibles par les membres des classes dérivées. 01/04/2023 Z.Dafir@emsi.ma 18
  • 19. Mode de derivation Résumé 01/04/2023 Z.Dafir@emsi.ma 19
  • 20. Heritage Public  Il donne aux membres publics et protégés de la classe de base le même statut dans la classe dérivée.  C’est la forme la plus courante d’héritage, car il permet de modéliser les relations "Y est une sorte de X" ou "Y est une spécialisation de la classe de base X". 01/04/2023 Z.Dafir@emsi.ma 20
  • 21. Heritage Public (Exemple) class Vehicule { public: void pub1(); protected: void prot1(); private: void priv1(); }; class Voiture : public Vehicule { class Voiture : public Vehicule { public: int pub2() { pub1(); // OK prot1(); // OK priv1(); // ERREUR } }; Voiture v; v.pub1(); // OK v.pub2(); // OK 01/04/2023 Z.Dafir@emsi.ma 21
  • 22. Heritage Privé  Il donne aux membres publics et protégés de la classe de base le statut de membres privés dans la classe dérivée.  Il permet de modéliser les relations "Y  Il permet de modéliser les relations "Y est composé de un ou plusieurs X".  Plutôt que d’hériter de façon privée de la classe de base X, on peut faire de la classe de base une donnée membre (composition). 01/04/2023 Z.Dafir@emsi.ma 22
  • 23. Heritage Privé (Exemple) class String { public: int length(); // ... }; class Telephone_number : private String { class Telephone_number : private String { void f1() { // ... l = length(); // OK }; Telephone_number tn; cout << tn.length(); // ERREUR 01/04/2023 Z.Dafir@emsi.ma 23
  • 24. Heritage Protégé  Il donne aux membres publics et protégés de la classe de base le statut de membres protégés dans la classe dérivée.  L’héritage fait partie de l’interface mais n’est pas accessible aux utilisateurs. 01/04/2023 Z.Dafir@emsi.ma 24
  • 25. Heritage Protégé (Exemple) class String { protected: int n; }; class Telephone_number : protected String { protected: protected: void f2() { n++; } // OK }; class Local_number : public Telephone_number { protected: void f3() { n++; } // OK }; 01/04/2023 Z.Dafir@emsi.ma 25
  • 26. Mode de derivation Résumé 01/04/2023 Z.Dafir@emsi.ma 26
  • 27. Redéfinition des méthodes dans la classe dérivée On peut redéfinir une fonction dans une classe dérivée si on lui donne le une classe dérivée si on lui donne le même nom que dans la classe de base. 01/04/2023 Z.Dafir@emsi.ma 27
  • 28. Redéfinition des méthodes dans la classe dérivée 01/04/2023 Z.Dafir@emsi.ma 28
  • 29. Redéfinition des méthodes dans la classe dérivée 01/04/2023 Z.Dafir@emsi.ma 29
  • 30. Redéfinition des méthodes dans la classe dérivée 01/04/2023 Z.Dafir@emsi.ma 30
  • 31. Redéfinition des méthodes dans la classe dérivée 01/04/2023 Z.Dafir@emsi.ma 31
  • 32. AJUSTEMENT d’accès  Lors d’un héritage protégé ou privé, nous pouvons spécifier que certains membres de la classe mère conservent leur mode d’accès la classe mère conservent leur mode d’accès dans la classe dérivée.  Ce mécanisme, appelé déclaration d’accès, ne permet en aucun cas d’augmenter ou de diminuer la visibilité d’un membre de la classe de base. 01/04/2023 Z.Dafir@emsi.ma 32
  • 33. L’héritage: les constructeurs  Les constructeurs par défaut des classes de bases sont automatiquement appelés avant le constructeur de la classe dérivée. constructeur de la classe dérivée. 01/04/2023 Z.Dafir@emsi.ma 33
  • 34. L’héritage: les constructeurs  Lors de l’instanciation d’une classe dérivée, il faut initialiser: Les attributs propres à la classe dérivée. Les attributs hérités de la classe mère. Les attributs hérités de la classe mère. Mais il ne doit pas être à la charge du concepteur de la classe dérivée de réaliser lui-même l’initialisation des attributs hérités. 01/04/2023 Z.Dafir@emsi.ma 34
  • 35. L’héritage: les constructeurs  L’accès à ces attributs pourrait être interdit! (private).  L’initialisation des attributs hérités doit donc se faire au niveau de la classe où ils sont faire au niveau de la classe où ils sont explicitement définis.  Solution: L’initialisation des attributs hérités doit se faire en invoquant les constructeurs de la classe mère. 01/04/2023 Z.Dafir@emsi.ma 35
  • 36. L’héritage et les constructeurs  L’invocation du constructeur de la classe mère se fait au début de la section d’appel aux constructeurs des attributs. aux constructeurs des attributs. 01/04/2023 Z.Dafir@emsi.ma 36
  • 37. L’héritage: les constructeurs  Lorsque la classe mère admet un constructeur par défaut, l’invocation explicite de ce constructeur dans la classe explicite de ce constructeur dans la classe dérivée n’est pas obligatoire.  Le compilateur se charge de réaliser l’invocation du constructeur par défaut. 01/04/2023 Z.Dafir@emsi.ma 37
  • 38. L’héritage: les constructeurs  Si la classe mère n’admet pas de constructeur par défaut, l’invocation explicite d’un de ses constructeurs est explicite d’un de ses constructeurs est obligatoire dans le constructeur de la classe dérivée.  La classe dérivée doit admettre au moins un constructeur explicite. 01/04/2023 Z.Dafir@emsi.ma 38
  • 43. L’héritage: les constructeurs Exemple de la classe véhicule 01/04/2023 Z.Dafir@emsi.ma 43
  • 44. L’héritage: les constructeurs Exemple de la classe avion 01/04/2023 Z.Dafir@emsi.ma 44
  • 45. L’héritage: les destructeurs  L’appel des destructeurs se fera dans l’ordre inverse des constructeurs. 01/04/2023 Z.Dafir@emsi.ma 45
  • 46. L’héritage: les destructeurs Exemple de la classe véhicule et la classe avion 01/04/2023 Z.Dafir@emsi.ma 46
  • 47. L’héritage: les destructeurs Exemple de la classe véhicule et la classe avion  Le destructeur de la classe avion est appelé en premier.  Il faut d’abord détruire l’avion et le véhicule sera détruit par la suite. 01/04/2023 Z.Dafir@emsi.ma 47 détruit par la suite.
  • 48. L’Héritage et la surcharge des opérateurs  A l'exception de la fonction d'affectation operator=( ), toutes les fonctions à opérateurs surchargés d'une classe A sont transmises par héritage à la classe dérivée B, avec les règles de résolution standard pour les fonctions surchargées.  Les fonctions à opérateurs surchargés définis à l’intérieur de la classe de base(surcharge interne) peuvent être transmises par héritage à la classe dérivée.  Les fonctions à opérateurs surchargés définis à l’extérieur de la classe de base(surcharge externe) ne peuvent pas être appelées dans la classe dérivée, car elles ne sont pas des fonctions de la classe de base. 01/04/2023 Z.Dafir@emsi.ma 48
  • 49. L’Héritage et la surcharge des opérateurs 01/04/2023 Z.Dafir@emsi.ma 49
  • 50. L’Héritage et la surcharge des opérateurs  Le constructeur de copie et l'opérateur d'affectation sont les deux manières d'initialiser un objet à l'aide d'un autre objet.  La différence fondamentale entre le constructeur de  La différence fondamentale entre le constructeur de copie et l'opérateur d'affectation réside dans le fait que le constructeur de copie alloue une mémoire distincte aux deux objets, à savoir le nouvel objet cible créé et l'objet source.  L' opérateur d'affectation alloue le même emplacement mémoire au nouvel objet cible ainsi que objet source. 01/04/2023 Z.Dafir@emsi.ma 50
  • 51. L’Héritage et la surcharge des opérateurs -exemple  La surcharge de l’opérateur d’affectation se fait à l’intérieur de la classe.  Exemple : class vehicule { double vitesse; double vitesse; int nbre_passagers; public: vehicule operator=(vehicule const&v){ vitesse= v.vitesse; nbre_passagers=v.nbre_passagers; cout<<"vehicule"; return *this; }}; vehicule v2=v1;//appel du constructeur par copie v2=v1;//appel à l'opérateur d'affectation 01/04/2023 Z.Dafir@emsi.ma 51
  • 52. L’Héritage et la surcharge des opérateurs -exemple  Avant de redéfinir l’opérateur ‘==‘ pour la classe véhicule, on ne peut pas tester l’égalité de deux véhicules dans le main par exemple if (v1==v2) cout<< « les véhicules sont identiques ». Cela n’est pas possible car cet opérateur n’est pas défini pour l’objet véhicule. Et donc il est nécessaire de redéfinir cet opérateur pour la classe véhicule. class vehicule { class vehicule { public: bool operator==(vehicule const &v){ if (vitesse==v.vitesse && nbre_passagers==v.nbre_passagers)return true; else return false; }};//fin de la classe véhicule Maintenant si on fait le test suivant dans le main: vehicule v1(300,5), v2(300,5);//création de deux objets véhicule if(v1==v2) cout<<"les mêmes véhicules";//le test avec l’opérateur == Cela va nous afficher les mêmes véhicules . 01/04/2023 Z.Dafir@emsi.ma 52
  • 53. L’Héritage et la surcharge des opérateurs -exemple  On peut même tester l’égalité de deux avions si on considère la classe avion qui hérite de la classe véhicule : class avion:public vehicule { int nbre_moteurs; …. …. }; • Après avoir redéfini l’opérateur ‘==‘ pour la classe véhicule qui est la classe de base, on peut tester l’égalité de deux avions, en faisant dans le main par exemple : • if(a1==a2) cout<<"les mêmes avions";//le test avec l’opérateur == de la classe véhicule . • Mais ce test ne va pas inclure le nombre de moteurs qui est un attribut propre à la classe dérivée (avion). Si on veut tester l’égalité des deux avions en incluant l’attribut qui est propre à la classe avion, il faut redéfinir cet opérateur pour la classe avion. 01/04/2023 Z.Dafir@emsi.ma 53
  • 54. L’Héritage et la surcharge des opérateurs -exemple • Pour redéfinir l’opérateur ‘==‘ pour la classe dérivée on peut appeler celui de la classe mère (classe véhicule), car la fonction de surcharge de l’opérateur ‘==‘ de la classe véhicule est défini à l’intérieur de la classe (une fonction de la classe). bool operator==(avion const &a){ bool operator==(avion const &a){ return (vehicule::operator==(a)&& (nbre_moteurs==a.nbre_moteurs)) ? true:false; } vehicule::operator==(a): appel de la fonction operator== de la classe véhicule qui est la classe de base. 01/04/2023 Z.Dafir@emsi.ma 54
  • 55. Récapitulatif  Une classe dérivée hérite tous les membres de la classe de base sauf : les constructeurs, le destructeur, et les opérateurs.  Les constructeurs ne sont pas hérités directement mais  Les constructeurs ne sont pas hérités directement mais sont utilisés dans la liste d’initialisation des constructeurs de la classe dérivée.  Le destructeur est utilisé automatiquement à la destruction de l’objet.  Les opérateurs doivent être redéfinis par la classe dérivée en appelant ceux de la classe de base. 01/04/2023 Z.Dafir@emsi.ma 55
  • 56. Héritage et amitié L’amitié pour une classe s’hérite, mais uniquement sur les membres de la classe hérités, elle ne se propage pas aux nouveaux hérités, elle ne se propage pas aux nouveaux membres de la classe dérivée et ne s’étend pas aux générations suivantes. 01/04/2023 Z.Dafir@emsi.ma 56
  • 57. Héritage et amitié- Exemple 01/04/2023 Z.Dafir@emsi.ma 57
  • 58. Héritage et amitié  L’amitié pour une fonction ne s’hérite pas.  A chaque dérivation, vous devez redéfinir les relations d’amitié avec les fonctions. 01/04/2023 Z.Dafir@emsi.ma 58
  • 59. Récapitulatif  L'héritage permet de spécialiser une classe.  Lorsqu'une classe hérite d'une autre classe, elle récupère toutes ses propriétés et ses méthodes.  Faire un héritage a du sens si on peut dire que l'objet A "est un" objet B . Par exemple, une Voiture "est un" Vehicule . La classe de base est appelée classe mère, et la classe qui en hérite  La classe de base est appelée classe mère, et la classe qui en hérite est appelée classe fille.  Les constructeurs sont appelés dans un ordre bien précis : classe mère, puis classe fille.  En plus de public et private , il existe une portée protected , équivalente à private mais plus ouverte : les classes filles peuvent elles aussi accéder aux éléments.  Si une méthode a le même nom dans la classe fille et la classe mère, c'est la méthode la plus spécialisée, celle de la classe fille, qui est appelée. 01/04/2023 Z.Dafir@emsi.ma 59
  • 62. Définition • L’héritage multiple est un mécanisme de programmation orientée objet dans lequel une classe peut hériter de comportements et de fonctionnalités de comportements et de fonctionnalités de plus d'une super-classe. • Il s'oppose à l'héritage simple, dans lequel une classe ne peut hériter que d'une seule super-classe. 01/04/2023 Z.Dafir@emsi.ma 62
  • 63. Définition Classe A2 Classe A1 01/04/2023 Z.Dafir@emsi.ma 63 Classe B
  • 64. Syntaxe • class A1 { . . . }; • class A2 { . . . }; class B : [public, protected ou private] • class B : [public, protected ou private] A1, [public, ...] A2 { . . . }; 01/04/2023 Z.Dafir@emsi.ma 64
  • 65. Syntaxe générale • class nomSousClasse : public nomSuperClasse1, …………….., public NomSuperClasseN { … public NomSuperClasseN { … }; • L’ordre de déclaration des super-classes est pris en compte lors de l’invocation des constructeurs/ destructeurs. 01/04/2023 Z.Dafir@emsi.ma 65
  • 66. Héritage multiple- constructeurs/destructeurs Comme pour l’héritage simple, l’initialisation des attributs hérités doit être faite par invocation des constructeurs des super-classes. constructeurs des super-classes. 01/04/2023 Z.Dafir@emsi.ma 66
  • 67. Héritage multiple- constructeurs/destructeurs • Syntaxe: SousClasse (liste de paramètres): SuperClasse1(arguments1),…………………. ,SuperClasseN(argumentsN),atrribut1 (valeur1), ……..,attributk(valeurk) (valeur1), ……..,attributk(valeurk) { } 01/04/2023 Z.Dafir@emsi.ma 67
  • 68. Héritage multiple- constructeurs/destructeurs • Lorsque l’une des super-classes admet un constructeur par défaut, il n’est pas nécessaire de l’invoquer explicitement. • L’exécution des constructeurs des super- classes se fait selon l’ordre de la déclaration d’héritage. 01/04/2023 Z.Dafir@emsi.ma 68
  • 69. Héritage multiple- constructeurs/destructeurs  L’ordre des appels des destructeurs des super-classes est l’inverse de celui des appels des constructeurs. 01/04/2023 Z.Dafir@emsi.ma 69
  • 70. Héritage multiple-Accès aux membres de la super-classe  Comme dans le cas de l’héritage simple, une sous classe peut accéder directement aux attributs et méthodes protégés ou publics de la super-classe. publics de la super-classe.  Que fait-il lorsque les attributs/méthodes portent le même nom dans plusieurs super- classes? 01/04/2023 Z.Dafir@emsi.ma 70
  • 74. Exemple –Solution 1 01/04/2023 Z.Dafir@emsi.ma 74
  • 75. Exemple –Solution 2 • Une des solutions consiste à lever l’ambigüité en indiquant explicitement dans la sous classe quelle(s) méthode(s) on veut invoquer. 01/04/2023 Z.Dafir@emsi.ma 75
  • 76. Exemple –Solution 3 • La meilleure solution consiste à ajouter dans la sous-classe une méthode définissant la bonne interprétation de l’invocation ambigüe. 01/04/2023 Z.Dafir@emsi.ma 76
  • 78. Plan Définition Les types de polymorphisme La résolution statique des liens 01/04/2023 Z.Dafir@emsi.ma 78 Méthodes virtuelles Références et pointeurs La résolution dynamique des liens
  • 79. Définition  Le polymorphisme est un concept de POO qui fait référence à la capacité d'une variable, d'une fonction ou d'un objet à prendre plusieurs formes.  Dans le cas du polymorphisme, les objets d'une classe appartenant au même arbre hiérarchique (hérités d'une classe mère commune) peuvent avoir des fonctions portant le même nom, mais ayant des comportements différents. 01/04/2023 Z.Dafir@emsi.ma 79
  • 80. Définition  Un objet polymorphe est un objet susceptible de prendre plusieurs formes pendant l’exécution.  Le polymorphisme est implémenté en C++ avec les fonctions virtuelles (virtual) et l’héritage. 01/04/2023 Z.Dafir@emsi.ma 80
  • 81. Définition  Le polymorphisme permet de manipuler des objets d'une classe fille via des pointeurs ou des références sur une classe mère. classe mère. 01/04/2023 Z.Dafir@emsi.ma 81
  • 82. Définition  En grec, "poly" signifie "plusieurs" et "morphe" signifie "forme".  Le but est donc de créer du code  Le but est donc de créer du code fonctionnant de différentes manières selon le type qui l'utilise.  Deux concepts sont nécessaires : des fonctions virtuelles et des pointeurs ou références sur l'objet. 01/04/2023 Z.Dafir@emsi.ma 82
  • 83. Types de polymorphisme Polymorphisme 01/04/2023 Z.Dafir@emsi.ma 83 le polymorphisme au moment de la compilation le polymorphisme au moment de l'exécution
  • 84. Types de polymorphisme  Le polymorphisme au moment de la compilation (method overloading): plusieurs fonctions avec la même signature. signature.  Le polymorphisme au moment de l'exécution (method overriding): la redéfinition de fonctions. 01/04/2023 Z.Dafir@emsi.ma 84
  • 85. Types de polymorphisme -exemple  Le polymorphisme au moment de la compilation: int somme(int a, intb){}//somme(1,2) double somme(double x, double y){}//somme(0.5,9.6) double somme(double x, double y){}//somme(0.5,9.6)  Le polymorphisme au moment de l'exécution: Etudiant e; e.afficher();// la fonction afficher existe dans la classe mère Personne et dans la classe fille Etudiant 01/04/2023 Z.Dafir@emsi.ma 85
  • 86. Polymorphisme - Exemple class Vehicule { public: void affiche() const; //Affiche une description du Véhicule protected: int m_prix; //Chaque véhicule a un prix }; class Voiture : public Vehicule //Une Voiture EST UN Véhicule { public: public: void affiche() const; private: int m_portes; //Le nombre de portes de la voiture }; class Moto : public Vehicule //Une Moto EST UN Véhicule { public: void affiche() const; private: double m_vitesse; //La vitesse maximale de la moto }; 01/04/2023 Z.Dafir@emsi.ma 86
  • 87. Polymorphisme - Exemple Le corps des fonctions affiche des différentes classes: void Vehicule::affiche() const { cout << "Ceci est un vehicule." << endl; } void Voiture::affiche() const { cout << "Ceci est une voiture." << endl; } void Moto::affiche() const { cout << "Ceci est une moto." << endl; } 01/04/2023 Z.Dafir@emsi.ma 87
  • 88. Polymorphisme - Exemple  Chaque classe affiche un message différent.  La fonction affiche de la classe mère a  La fonction affiche de la classe mère a été masqué après la redéfinition de la fonction dans les classes filles. 01/04/2023 Z.Dafir@emsi.ma 88
  • 89. Exemple int main() { Vehicule v; v.affiche(); //Affiche "Ceci est un vehicule." Moto m; m.affiche(); //Affiche "Ceci est une moto." return 0; } 01/04/2023 Z.Dafir@emsi.ma 89
  • 90. La résolution statique des liens void presenter(Vehicule v) //Présente le véhicule passé en argument { v.affiche(); } int main() { Vehicule v; presenter(v); Moto m; presenter(m); return 0; } 01/04/2023 Z.Dafir@emsi.ma 90
  • 91. La résolution statique des liens • Les messages affichés: Ceci est un vehicule. Ceci est un vehicule. • Le message n'est pas correct pour la moto ! C'est comme si, lors du passage dans la fonction, la vraie nature de la moto s'était perdue, et qu'elle était redevenue un simple véhicule. 01/04/2023 Z.Dafir@emsi.ma 91
  • 92. La résolution statique des liens • En termes techniques, on parle de résolution statique des liens. • La fonction reçoit un Vehicule , c'est • La fonction reçoit un Vehicule , c'est donc toujours la version Vehicule des méthodes qui sera utilisée. 01/04/2023 Z.Dafir@emsi.ma 92
  • 93. La résolution statique des liens • C'est le type de la variable qui détermine quelle fonction membre appeler, et non sa vraie nature. void presenter(Vehicule v) //Présente le void presenter(Vehicule v) //Présente le véhicule passé en argument { v.affiche(); } 01/04/2023 Z.Dafir@emsi.ma 93
  • 94. La résolution dynamique des liens • Le programme utilise la bonne version des méthodes car il sait si l'objet est de type mère ou de type fille. • L’adaptation de la méthode au type de l’objet exécuté. 01/04/2023 Z.Dafir@emsi.ma 94
  • 95. La résolution dynamique des liens • Les méthodes virtuelles et les références. • Les méthodes virtuelles et les pointeurs. • Les méthodes virtuelles et les pointeurs. 01/04/2023 Z.Dafir@emsi.ma 95
  • 96. Les méthodes virtuelles • Pour déclarer une méthode virtuelle, il suffit d'ajouter le mot-clé virtual dans le prototype de la classe (dans le fichier .hpp) fichier .hpp) 01/04/2023 Z.Dafir@emsi.ma 96
  • 97. Exemple class Vehicule { public: virtual void affiche() const; //Affiche une description du Véhicule protected: int m_prix; //Chaque véhicule a un prix }; class Voiture : public Vehicule //Une Voiture EST UN Véhicule { public: public: virtual void affiche() const; private: int m_portes; //Le nombre de portes de la voiture }; class Moto : public Vehicule //Une Moto EST UN Véhicule { public: virtual void affiche() const; private: double m_vitesse; //La vitesse maximale de la moto }; 01/04/2023 Z.Dafir@emsi.ma 97
  • 98. Les méthodes virtuelles  Il n'est pas nécessaire de mettre virtual devant les méthodes des classes filles. Elles sont automatiquement virtuelles par automatiquement virtuelles par héritage.  Il n'est pas nécessaire que toutes les méthodes soient virtuelles. Une classe peut proposer des fonctions "normales" et d'autres virtuelles. 01/04/2023 Z.Dafir@emsi.ma 98
  • 99. Les méthodes virtuelles • Il ne faut pas mettre virtual dans le fichier .cpp , mais uniquement dans le .hpp 01/04/2023 Z.Dafir@emsi.ma 99
  • 100. Les références void presenter(Vehicule const& v) //Présente le véhicule passé en argument { v.affiche(); } int main() //Rien n'a changé dans le main() int main() //Rien n'a changé dans le main() { Vehicule v; presenter(v); Moto m; presenter(m); return 0; } 01/04/2023 Z.Dafir@emsi.ma 100
  • 101. Les références Ceci est un vehicule. Ceci est une moto. • Cela marche ! La fonction presenter() a bien appelé la bonne version de la bien appelé la bonne version de la méthode. En utilisant des fonctions virtuelles ainsi qu'une référence sur l'objet, la fonction presenter() a pu correctement choisir la méthode à appeler. 01/04/2023 Z.Dafir@emsi.ma 101
  • 102. Les pointeurs Vehicule *v; v=new Vehicule(); v->affiche(); Voiture vt; Moto m; Moto m; v=&vt; v->affiche();// v=&m; v->affiche();//le même pointeur la même fonction mais la sortie est différente 01/04/2023 Z.Dafir@emsi.ma 102
  • 103. Les pointeurs Ceci est un vehicule. Ceci est une voiture. Ceci est une moto. 01/04/2023 Z.Dafir@emsi.ma 103
  • 104. Les pointeurs void presenter(Vehicule *v){ v->affiche() ;} Vehicule *v; Voiture vt; Voiture vt; Moto m; v=&vt; presenter(v); v=&m; presenter(v);//le même pointeur 01/04/2023 Z.Dafir@emsi.ma 104
  • 105. Les pointeurs Ceci est une voiture. Ceci est une moto. 01/04/2023 Z.Dafir@emsi.ma 105
  • 106. Récapitulatif  Le polymorphisme représente la capacité du système à choisir dynamiquement la méthode qui correspond au type de l’objet en cours de correspond au type de l’objet en cours de manipulation.  Le polymorphisme est implémenté en C++ avec les fonctions virtuelles (virtual), les pointeurs ou les références. 01/04/2023 Z.Dafir@emsi.ma 106