• Aucun résultat trouvé

Programmation objet

N/A
N/A
Protected

Academic year: 2022

Partager "Programmation objet"

Copied!
35
0
0

Texte intégral

(1)

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

(2)

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 ?

(3)

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.

(4)

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

(5)

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.

(6)

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

(7)

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&);

};

(8)

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 ?

(9)

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.

(10)

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.

(11)

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.

(12)

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 ».

(13)

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é.

(14)

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 :

(15)

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.

(16)

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.

(17)

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é.

(18)

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é

(19)

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é

(20)

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

(21)

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 .

(22)

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() { ... }

(23)

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.

(24)

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.

(25)

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é.

(26)

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

(27)

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.

(28)

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.

(29)

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.

(30)

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.

(31)

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 ";};

};

(32)

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

(33)

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 !

(34)

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.

(35)

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 !

Références

Documents relatifs

Par exemple : std::string , qui obligatoirement doit faire des allocations de mémoire (pour stocker les caractères) et donc libérer, quoi qu'il arrive, même en cas d'exception

Plusieurs instances de cette classe devront référencer le même objet en mémoire : définition d'une sous-classe assistante, associant l'adresse réelle de l'objet et un compteur...

Une pile représente un ensemble de données où l'on ne peut accéder qu'au dernier élément entré, qui devient donc le premier à sortir. On les appelle parfois LIFO (last in

A présent le code peut s'utiliser pour afficher tous les éléments d'une liste d'entiers différents de -5, tous les éléments d'un tableau de chaînes de moins de trois

sinon si valeur dans feuille courante &lt; valeur à ajouter Prend branche gauche comme nouvelle racine Ajout. sinon si valeur dans feuille courante &gt; valeur à ajouter Prend

parenthèse ouvrante : on remarque que l'utilisation d'une pile peut simplifier la gestion des parenthèses pour la construction de l'arbre..... 15

• Arbre de recherche suivant la valeur Facile à programmer Très rapide à chercher Espace mémoire moyen Aucune n'est préférable, le contexte. décidera de la

Elle ne peut donc pas être appelée directement, mais doit être redéfinie dans. les