Télécharger la présentation
La présentation est en train de télécharger. S'il vous plaît, attendez
Publié parFleuretta Chambon Modifié depuis plus de 10 années
2
Héritage Licence Informatique Besançon Méthode et Outils pour la Programmation Françoise Greffier
3
LES FORMES GEOMETRIQUES Où l’on propose une application permettant de : Dessiner un carré, un rectangle, un cercle, un triangle …. Associer au dessin : périmètre et surface.
4
CLASSE FORME enum categorie { carre, rectangle, cercle, triangle}; class figure {public:... void dessiner (void); double périmètre (void); double surface (void);... private : categorie c; double a,b; point centre; };
5
IMPLANTATION double figure::surface(void) {switch c { case carre : return (a*a); case rectangle : return (a*b);... } }
6
POURQUOI HERITER ? Relier des objets entre eux (famille) Factoriser des traitements (Réutilisabilité) Représenter le centre de la figure (généralisation) IDENTIFICATION DES OBJETS Un cercle (rayon) ne « ressemble » pas à un rectangle (diagonale) Faciliter l ’extension l’application (Extensibilité) On traite les ellipses
7
COMMENT HERITER ? GESTION D’UNE HIERARCHIE DE CLASSES Factorisation Toute figure géométrique a un centre Spécialisation (un objet est un cas particulier d ’un autre objet) Un carré est un cas particulier de rectangle Enrichissement (un objet a des propriétés propres) Un triangle rectangle comprend le calcul de l’hypoténuse
8
GRAPHE D’HERITAGE Figure PolygoneEllipse ParallélogrammetriangleCercle Rectangletriangle rectangle Hérite de
9
RELATION D’HERITAGE La classe D hérite de la classe M M Classe mère D Classe dérivée Héritage simple : Un unique ascendant direct
10
HERITAGE PUBLIC • Les classes dérivées héritent de la classe mère en se spécialisant • Les membres public de la classe mère deviennent des membres public des classes dérivées. • Les classes dérivées peuvent avoir des membres supplémentaires. (enrichissement) Héritage public Relation : « est une sorte de »
11
HERITAGE public en C++ class M {public : void f(void); void g(void); private:... }; class D: {public : Méthodes redéfinies : void f(void); Méthodes supplémentaires : void h(void); private: Caractéristiques supplémentaires }; public M L ’instance W de la classe D a accès à la section public des classes D et M
12
Partage des caractéristiques class M {public :... protected : private: }; class D: {public :... private: Caractéristiques supplémentaires }; public M Pour la classe D : les membres de la section protected de la classe mère M sont accessibles par ses fonctions membres et fonctions amies Pour la classe M : les membres de la section protected se comportent comme s’ils étaient placés dans sa section private.
13
HERITAGE : public Partage des caractéristiques class M {public : protected: private : }; class D : {public : protected: private : }; public M Partie inaccessible héritée
14
Accès aux caractéristiques class M {public :... protected : private: }; class D: {public :... private: Caractéristiques supplémentaires }; public M (ex: fonction main) accès aux sections public des classes M et D Vision utilisateur accès aux sections public et protected de la classe M Classe D
15
Accès aux caractéristiques class M {public :... protected : private: }; class D: {public :... private: Caractéristiques supplémentaires }; public M Attention : l ’utilisation du qualificateur protected est contraire au principe d ’encapsulation. Si des modifications sont apportées à la section protected de la classe M alors toutes les classes dérivées qui utilisent l ’accès direct à cette section sont susceptibles de subir des modifications.
16
Les constructeurs Lors de la création d ’une instance d ’une classe dérivée son constructeur et tous les constructeurs de ses classes parentes sont activés. Comme un objet d'une classe dérivée est un objet de la classe de base (classe mère) plus quelque chose, pour construire un objet de la classe dérivée il faut au préalable construire la partie de l'objet correspondant à la classe de base.
17
Les constructeurs class figure {public : figure (point); //construct :centre private : point centre; }; rectangle::rectangle(double a,double b,point c):figure (c) { lo=a; la=b; } public figure class rectangle : { public : rectangle(double,double,point); // constructeur par initialisation : //longueur et largeur, centre }; Appel du constructeur de la classe mère
18
Les constructeurs Héritage simple : Les constructeurs sont activés de la racine de l ’arbre d ’héritage vers les classes dérivées Activation : d ’un constructeur par défaut (qui doit exister) ou bien appel à un constructeur explicite.
19
Les destructeurs Lors de la destruction d’une instance d ’une classe dérivée son destructeur et tous les destructeurs de ses classes parentes sont activés. Héritage simple : Les destructeurs sont activés de la classe dérivée vers la racine de l ’arbre d ’héritage.
20
Fonctions surchargées class M {public : void f(void); void g(void); private :... Protected : }; class D1: {public : void f(void); void h(void); private: Caractéristiques supplémentaires }; class D2: {public : void f(void); void k(void); private: Caractéristiques supplémentaires }; public M
21
class M {public : void f(void); void g(void); private :... Protected : }; Fonctions surchargées (Liaison statique) D1 w1; D2 w2; w1.f( ); w2.g( ); Vision utilisateur class D1: {public : void f(void); void h(void);...}; public M class D2: {public : void f(void); void k(void); …}; public M Liaison statique Comment dans une hiérarchie par héritage, le compilateur sélectionne la méthode polymorphe à exécuter parmi les surcharges incluses dans la hiérarchie de classes ?
22
Fonctions surchargées. Liaison statique Résolution de la surcharge par liaison statique D1 w1; D2 w2; w1.f( ); w2.g( ); Vision utilisateur Classe M Classe D1 Classe D2 Le type de W1 est D1, par conséquent le compilateur regarde si la méthode f est dans la classe D1 Si oui, celle-ci est exécutée Si non, il la recherche dans la première classe ascendante, etc...
23
Héritage et COMPATIBILITE de type class M {... }; class D: {... }; M* ptrM; D d; ptrM=&d; D* ptrD; M m; ptrD=&m; On dit que le type statique(déclaré) de *ptrM est M. On dit que le type dynamique (réel) de *ptrM est D. L’objet pointé par ptrM reste de type D. Vision utilisateur public M
24
Collection d’objets de types différents { figure* Dessin[4]; // tableau de pointeurs sur figure Dessin[0]=new carré(); Dessin[1]=new rectangle(); Dessin[2]=new cercle(); Dessin[3]=new triangle();} Sur cet exemple, les composants du tableau Dessin ont un type statique = figure un type dynamique = carré ou rectangle...
25
Liaison statique des fonctions class figure { public : void tracer (void) { } //action vide }; class rectangle: { public : void tracer (void); //rectangle IC est tracé }; public figure figure* Ptr; Ptr = new rectangle(); Ptr -> tracer( ); Vision utilisateur Le type statique de *Ptr est figure. Par conséquent, l’instruction Ptr->tracer( ) active la méthode tracer de la classe figure. => Action vide
26
Polymorphisme La liaison dynamique est un mécanisme distinct (bien qu'étroitement lié) de l'héritage. C'est le fait qu'un nom de fonction membre d'une classe de base (classe mère) peut être associé à une fonction membre d'une classe dérivée. Ce mécanisme est essentiel dans la POO. Il permet de reléguer la réalisation d'une fonction membre à un descendant. Le polymorphisme : grâce à la liaison dynamique, un même nom de fonction pourra correspondre à des réalisations différentes suivant les classes dérivées. Le polymorphisme offre la possibilité d ’associer à une méthode un code différent selon l’objet auquel elle appartient. Exemples : f ou tracer pour les formes géométriques
27
Liaison dynamique des fonctions Fonctions virtuelles class figure { public : void tracer (void) { } //action vide }; class rectangle : public figure { public : void tracer (void); // instance courante est tracée }; figure* Ptr; Ptr = new rectangle( ); Ptr -> tracer( ); Vision utilisateur La fonction tracer est virtuelle. Par conséquent, l’instruction Ptr->tracer( ); active la méthode associée au type dynamique de *ptr. => Tracé du rectangle virtual
28
Les fonctions virtuelles Lors de la redéfinition d’une fonction virtuelle: Les fonctions virtuelles doivent avoir la même liste de paramètres. Les types de retour sont égaux ou sont des pointeurs compatibles. L’exécution des fonctions virtuelles s’appuie sur une indirection (table de pointeurs de fonctions virtuelles).
29
Classes dérivées : Tout comme une fonction ordinaire une fonction virtuelle sert de fonction par défaut dans les classes dérivées. Une fonction virtuelle redéfinie dans une classe dérivée reste virtuelle dans la classe dérivée même si cela n’est pas spécifié. Les fonctions virtuelles
30
Classe abstraite Une classe abstraite est une classe qui ne peut pas être instanciée. Exemple : l’instantiation de la classe figure n’a pas de sens. class figure { public : void tracer(void) ; }; Une classe abstraite est une classe qui contient au moins une méthode virtuelle pure, ou qui n'a pas redéfinit une méthode virtuelle pure. virtual =0 //méthode virtuelle pure Une méthode virtuelle pure est une méthode virtuelle dont le corps est explicitement non donné, on précise un =0 a la fin du prototype d'une telle méthode.
31
Méthode virtuelle pure Une classe abstraite est une classe dont aucun objet de ce type ne peut être créé. Ainsi l'abstraction de la classe se propagera dans les classes dérivées tant que la(les) méthode(s) virtuelle(s) pure(s) n'auront pas été redéfinie(s). Cela est relativement pratique dans le cas d'une classe définissant un concept général, et non une classe en elle même. Lorsqu'une classe définit une méthode virtuelle, le destructeur (s'il est défini) doit être obligatoirement virtuel (sinon on risque de n'appeler que le destructeur de la classe mère alors qu'il s'agit d'un objet de la classe fille). Attention !! Un constructeur ne peut pas être virtuel et il ne peut pas appeler de méthode virtuelle.
32
UTILISATION D’UNE CLASSE ABSTRAITE class figure { public : virtual void tracer (void)=0; //fonction virtuelle pure }; figure F; figure* Ptr; Ptr = new figure; Vision utilisateur //illégal // légal
33
HERITAGE PRIVE La classe D hérite de la classe M M Classe mère D Classe dérivée Héritage privé : La classe D restreint les fonctionnalités de M • Les membres public de la classe mère et protégés de la classe mère deviennent des membres privés des classes dérivées. • Les classes dérivées peuvent avoir des membres supplémentaires. Héritage privé
34
Héritage et contrôle d'accès Une classe dérivée dans sa déclaration spécifie de quelle(s) classe(s) elle hérite mais précise aussi le contrôle d'accès des membres hérités : dans tous les cas, ne peut être accessible dans la classe dérivée que la partie publique ou protégée de la classe de base si l'héritage est public, les membres publics et protégés de la classe de base sont respectivement publics et protégés dans la classe dérivée si l'héritage est privé, les membres publics et protégés de la classe de base sont privés dans la classe dérivée si l'héritage est protégé, les membres publics et protégés sont protégés dans la classe dérivée. on peut déclarer une classe dérivée comme friend dans la classe de base, permettant ainsi l'accès à tous les membres de la classe de base. par défaut, l'héritage est privé pour une class et public pour une struct
35
L ’opérateur dynamic_cast Opérateur de conversion de type Il a pour rôle d ’effectuer une conversion de type que si elle est réalisable au moment de l ’exécution. Il y a donc vérification du type REEL de l ’instance converti à l ’exécution. Opérateur appliqué sur un pointeur (Retourne NULL si la conversion échoue) ou sur une référence (Exception bad_cast à lever si conversion échoue sur une référence). Exemple : if(dynamic_cast Dessin[i])...
36
class M {public : protected: private : }; class D : {public : protected: private : }; private M Partie inaccessible héritée HERITAGE : private Partage des caractéristiques
37
HERITAGE PRIVE - Exemple class tableau {public: tableau (void); // Constructeur tableau (const tableau&); //const. par copie tableau& operator=(const tableau&); int& operator [ ](int); ~tableau (void); // Destructeur private : int * T; int nb; // nombre d’elements }; class pile:private tableau {public: pile (int n); // Constructeur void empiler (int) ; int depiler (void); int ValSommet (void); bool vide (void); ~pile (void); // destructeur private : int sommet; };
38
UTILISATION D’UNE PILE void main(void) { pile P(10); P.empiler(3); P [2] = 9; } Vision utilisateur class pile: private tableau {public: pile (int n); // Constructeur void empiler (int) ; int depiler (void); int ValSommet (void); bool vide (void);... }; illégal
39
Classe pile (implémentation) pile::pile (int n) {sommet = -1;} void pile::empiler (int e) {sommet += 1; (*this) [sommet]=e;} void pile::dépiler (void) {sommet -= 1;} int pile::ValSommet (void) {return (*this) [sommet];} bool pile::vide (void) {return sommet= = -1;}
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.