Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Programmation objet
Cours n°10
L'héritage ou la réutilisation aisée de l'existant
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Premier objectif de la POO :
Ré-utiliser le code déjà implémenté
Exemple : logiciel de gestion commerciale
Toute commande contient certaines données, quelque soit le métier :
- Date - Numéro - Client ...
Pourquoi redéfinir celles-ci dans chaque logiciel ?
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Principe de l ’héritage :
Définir une fois pour toutes les composantes communes Construire des « briques » logicielles de base et les
utiliser pour définir des nouvelles, plus spécialisées.
Définir des objets de base regroupant l ’ensemble des fonctionnalités et données communes
Créer des objets dérivés qui héritent des propriétés de base.
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Une relation d ’héritage est composée de deux éléments :
Une classe mère ou classe de base.
Une classe fille ou classe dérivée.
La classe fille contient une partie héritée de la classe mère qui peut être considérée comme une instance de celle-ci.
espace hérité = espace spécifique :
enrichissements "instance" mère Mère : Classe de base
classe dérivée
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
L ’héritage n ’est pas limité à un seul niveau.
Une classe fille peut elle-même être la mère d ’autres classes.
Une classe peut posséder une mère (héritage simple) ou plusieurs (héritage multiple).
Les relations mère-fille d ’héritage décrivent une arborescence plus ou moins complexe.
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
A
B C
D E
H
Arborescence avec héritage simple
A
B C
D E
H
Arborescence avec héritage multiple Classe Mère Classe Fille
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Exemple d ’héritage simple : classe POINT
Pour gérer les points d ’un plan, on définit une classe POINT :
class POINT {
protected: // accès comme privé float x;
float y;
public:
POINT(float a=0,float b=0) :x(a), y(b){}
friend ostream&
operator<<(ostream&,const POINT&);
};
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Avec par exemple la fonction gérant l ’affichage par flux : ostream& operator<<(ostream& flux,const POINT& p)
{
flux<<"("<<p.x<<";"<<p.y<<")";
return flux;
}
Cette classe peut bien sûr comporter des méthodes pour déplacer, recopier le point, etc...
Que se passe-t-il si nous avons besoin d ’ajouter une caractéristique : la couleur par exemple ?
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
En POO, il nous suffit de définir une classe dérivée de POINT, qui ne contiendra que des données et fonctionnalités spécifiques.
Si l ’on veut un point coloré, il possède de toutes façons des coordonnées x et y. Inutile donc de les redéfinir.
Seule, la donnée couleur a besoin d ’être redéfinie, ainsi que toutes fonctions traitant la couleur.
Examinons la classe POINT_COLORE, classe fille de POINT.
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
class POINT_COLORE: public POINT {
private:
int Couleur;
public:
POINT_COLORE(void);
POINT_COLORE(float,float,int);
POINT_COLORE(POINT&,int);
friend ostream&
operator<<(ostream&,POINT_COLORE&);
};
On remarque que seule la donnée Couleur est précisée.
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Examinons les constructeurs de POINT_COLORE : POINT_COLORE::POINT_COLORE()
:POINT(), Couleur(0) {
}
On remarque qu ’il faut appeler le constructeur de la classe mère afin d ’initialiser (construire) la partie
« héritée » de la classe fille.
Ici c ’est le constructeur par défaut qui sera appelé, les propriétés x et y seront donc initialisés à 0.
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
POINT_COLORE::POINT_COLORE (float a,float b,int c)
:POINT(a,b),Couleur(c) {
}
Ici on précise les trois paramètres : le constructeur approprié est donc appelé pour initialiser les données héritées de la mère.
Le constructeur de la fille ne construit que sa partie
« propre ».
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
POINT_COLORE::POINT_COLORE
(const POINT& p,int c):POINT(p) Couleur(c)
{ }
Dans ce cas on construit un POINT_COLORE à partir d ’un POINT : le constructeur par recopie de la classe mère est appelé.
Il faut noter que si aucun constructeur de la classe mère n ’est appelé explicitement, le compilateur appelle le constructeur par défaut. Ceci est à éviter pour des raisons de lisibilité.
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Le code suivant : void main(void) {
POINT P;
cout << "\nPoint :"<<P;
POINT P2(3,5);
cout << "\nPoint 3,5 :"<<P2;
POINT_COLORE P3;
cout << "\nPoint coloré"<<P3;
POINT_COLORE P4(1,-5,10);
cout << "\nPoint coloré P4"<<P4;
POINT_COLORE P5(P2,56);
cout << "\nPoint coloré P5"<<P5;
}
Point : (0;0)
Point 3,5 : (3;5)
Point coloré : (0;0;0)
Point coloré P4 :(1;-5;10) Point coloré P5 (3;5;56)
Affichera :
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Accès aux membres hérités
Tous les membres publics d ’une classe de base sont accessibles dans sa classe dérivée.
Les membres privés sont par contre inaccessibles.
Problème : impossible donc de les utiliser dans la classe dérivée.
1ere Solution : déclarer toutes les données d ’une classe de base comme publiques.
Ceci est risqué, on perd l ’intérêt de la protection des données (encapsulation). Il faut l'éviter.
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Le C++ apporte une solution plus fiable : un autre mode d ’accès : le mode protégé (protected)
Un membre protégé se comporte comme un membre privé vis-à-vis de l ’extérieur de sa classe.
Il se comporte comme un membre public pour les classes dérivées.
On peut donc par ce moyen protéger des données de l ’extérieur tout en les laissant accessibles pour les classes dérivées.
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Différents modes d ’héritage Il existe trois modes héritage :
• le mode public
• le mode privé
• le mode protégé
Chaque mode influence l ’accès aux données héritées.
Le mode privé est choisi par défaut si aucun n ’est précisé.
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
L ’héritage privé
class T_Fille : private T_Mere {...};
Les effets sur l ’accessibilité des propriétés sont les suivants :
Classe mère Classe fille inaccessible inaccessible
privé inaccessible
protégé privé
public privé
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
L ’héritage protégé
class T_Fille : protected T_Mere {...};
Les effets sur l ’accessibilité des propriétés sont les suivants :
Classe mère Classe fille inaccessible inaccessible
privé inaccessible
protégé protégé
public protégé
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
L ’héritage public
class T_Fille : public T_Mere {...};
Les effets sur l ’accessibilité des propriétés sont les suivants :
Classe mère Classe fille inaccessible inaccessible
privé inaccessible
protégé protégé
public public
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Amitié et héritage
Une fonction ou classe amie d ’une classe M reste amie de la classe dérivée F mais uniquement pour les membres hérités de M.
L ’amitié ne s ’hérite pas : une classe B qui hérite d ’une classe A , amie de M, n ’a aucun accès
particulier aux membres de M .
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Redéfinition des méthodes hérités Reprenons l ’exemple de la classe POINT, en y ajoutant une fonction affiche :
void POINT::Affiche() {
cout<< x << "; "<< y;
}
La classe dérivée POINT_COLORE pourrait, elle aussi, avoir besoin d ’une fonction similaire :
void POINT_COLORE::Affiche() { ... }
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Il est bien entendu possible de redéfinir la fonction affiche. Ceci n'est pas une surcharge (prototypes identiques).
La fonction dérivée cache donc la fonction de la classe mère.
Cette fonction pourrait se définir comme : void POINT_COLORE::Affiche() {
cout << x <<";"<< y
<<";"<< Couleur;
}
On remarque qu ’une partie du code est identique à celui de la fonction mère.
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Il est dommage de répéter le même code. On peut, dans ce cas, appeler la fonction de la classe mère grâce à l ’opérateur de portée :
void POINT_COLORE::Affiche() {
POINT::Affiche();
cout << ";" << Couleur ; }
De plus, cette solution est la seule possible si Affiche utilise des membres privés (et non protégés) de la classe mère. Elle est donc systématiquement préférée.
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Héritage des constructeurs
Lors de la création d ’un objet (sa construction) le compilateur appelle automatiquement le
constructeur de l ’objet.
Si celui-ci est dérivé d ’une autre classe, il doit appeler le constructeur de celle-ci.
Si ce n ’est pas fait explicitement, le
constructeur par défaut de la classe de base est appelé.
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Exemple : class M
{
//....
M();
M(int , char);
};
class F:public M {
//....
F();
F(int, char, float);
};
F::F():M()
{ //.... } // construction spécifique de F
F::F(int a, char b, float x):M(a,b) { //.... } // partie spécifique de F
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Héritage des destructeurs
Un destructeur est unique pour une classe.
Il est donc inutile de préciser, lors de la
destruction d ’un objet dérivé, le destructeur de l ’objet de base.
Le destructeur de la classe de base est appelé automatiquement après le destructeur de la classe dérivée.
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Héritage du constructeur par recopie
Constructeur un peu particulier.
Il existe plusieurs cas à considérer :
Aucune classe ne possède de constr. par recopie.
La classe dérivée ne possède pas de constr. par recopie.
La classe dérivée possède son propre constr. par recopie.
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Aucune classe ne possède de constr. par recopie Si une instruction du type
F f1;
F f2 = f1;
est présente, le compilateur réalisera une simple recopie bit à bit des données de F (donc des
données de M également).
Attention donc dans le cas de données pointeurs.
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
La classe dérivée ne possède pas de constr. par recopie La recopie s ’effectue en deux temps :
• Recopie octet par octet des propriétés
spécifiques de la classe dérivée (recopie par défaut)
• Appel du constructeur par recopie de la classe mère afin d ’initialiser les propriétés héritées.
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Exemple : class M {
int a,b;
M(int a1=0, int b1=0):a(a1),b(b1) {cout<<" CM ";};
M(M& m):a(m.a),b(m.b)
{cout<<" CM& ";};
};class F:public M {
float x;
F():x(0){cout<<" CF ";};
};
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Les appels : Donneront l ’affichage : M m1(5,4); CM (appel du constr. De M)
m1 contient 5 et 4.
M m2=m1; CM& (appel du c. Par recopie) m2 contient 5 et 4.
F f1; CM (appel du constr de M)
CF (appel du constr. De F) f1 contient 0,0,0
F f2=f1; CM& (appel du c. Par recopie) f2 contient 0,0,0
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
La classe dérivée possède son propre constr. par recopie Le constructeur par recopie dérivé cache
complètement le constructeur par recopie de la classe mère.
Il faut donc gérer la recopie des membres hérités.
Si aucun constructeur pour la classe de base n ’est spécifié :
F::F(F& f) { //.... } Le compilateur appellera le constructeur par
défaut de M : il n ’y aura donc pas de recopie des membres hérités !
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Il faut donc obligatoirement spécifier le
constructeur par recopie de M dans la liste d ’initialisation de F :
F::F(F& f):M(f)
{ //.recopie des membres spéc.};
Normalement, le constructeur par recopie de M demande une référence sur un objet de type M.
Or ici, l ’objet passé en paramètre est de type F.
Le type dérivé F est donc vu comme pouvant être de type M
Cette propriété est appelée polymorphisme.
Héritage Héritage
Introduction Principes Exemple
Accès aux membres Modes d’héritage Amitié et héritage Surcharge de méthodes
Prochain cours :
POLYMORPHISME D' HERITAGE
A la semaine prochaine !