290 likes | 376 Views
Leçon 3 : Héritage. IUP 2 Génie Informatique Méthode et Outils pour la Programmation Françoise Greffier. 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.
E N D
Leçon 3 : Héritage IUP 2 Génie Informatique Méthode et Outils pour la Programmation Françoise Greffier
LES FORMESGEOMETRIQUES 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.
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; };
IMPLANTATION doublefigure::surface(void) {switch c { case carre : return (a*a); case rectangle : return (a*b); . . . } }
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
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
GRAPHE D’HERITAGE Hérite de Figure Polygone Ellipse Parallélogramme triangle Cercle Rectangle triangle rectangle
M Classe mère D Classe dérivée RELATION D’HERITAGE La classe D hérite de la classe M Héritage simple : Un unique ascendant direct
HERITAGE PUBLIC Héritage public Relation : « est une sorte de » • 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)
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 aaccès à la section publicdes classes D et M
Partage des caractéristiques class D: {public : ... private: Caractéristiques supplémentaires }; public M class M {public : ... protected : private: }; Pour la classe D : les membres de la section protectedde la classe mère M sont accessibles par ses fonctions membres et fonctions amies Pour la classe M : les membres de la section protectedse comportent comme s’ils étaient placés dans sa section private.
Partie inaccessible héritée HERITAGE : publicPartage des caractéristiques public M class D : {public : protected: private : }; class M {public : protected: private : };
class D: {public : ... private: Caractéristiques supplémentaires }; public M Classe D Vision utilisateur (ex: fonction main) accès aux sections public des classes M et D accès aux sections public et protected de la classe M Accès aux caractéristiques class M {public : ... protected : private: };
class D: {public : ... private: Caractéristiques supplémentaires }; public M Accès aux caractéristiques class M {public : ... protected : private: }; 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.
public figure Appel du constructeur de la classe mère Les constructeurs class rectangle : { public : rectangle(double,double,point); // constructeur par initialisation : //longueur et largeur, centre }; class figure {public : figure (point); //construct :centre private : point centre; }; rectangle::rectangle(double a,double b,point c):figure (c) { lo=a; la=b; }
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. • 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.
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.
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 }; Fonctions polymorphes public M public M 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
class M {public : void f(void); void g(void); private :. . . Protected : }; class D2 : {public : void f(void); void k(void); …}; class D1: {public : void f(void); void h(void);...}; public M public M D1 w1; D2 w2; w1.f( ); w2.g( ); Vision utilisateur Fonctions polymorphes (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 ? Liaison statique
Vision utilisateur Classe M D1 w1; D2 w2; w1.f( ); w2.g( ); Classe D1 Classe D2 Fonctions polymorphes (surcharge ) Liaison statique Le type de W1 est D1, par conséquent le compilateur regarde si la méthode f est dans la classe D1Si oui, celle-ci est exécutée Si non, il la recherche dans la première classe ascendante, etc... Résolution de la surcharge par liaison statique
Vision utilisateur M* ptrM; D d; ptrM=&d; D* ptrD; M m; ptrD=&m; Héritage et COMPATIBILITE de type class M { . . . }; class D : { . . . }; public M On dit que le type statique de *ptrM est M. On dit que le type dynamique de *ptrM est D. L’objet pointé par ptrM reste de type D.
Collection d’objets de types différents { figure* T[4]; // tableau de pointeurs // sur figure T[0]=new carré(); T[1]=new rectangle(); T[2]=new cercle(); T[3]=new triangle(); } Sur cet exemple, les composants du tableau T ont • un type statique = figure • un type dynamique = carré ou rectangle ...
Vision utilisateur public figure Action vide Liaison statique des fonctions class figure { public : void tracer (void) { } //action vide }; class rectangle: { public : void tracer (void); //rectangle IC est tracé }; figure* Ptr; Ptr = new rectangle(); Ptr -> tracer( ); Le type statique de *Ptr est figure. Par conséquent, l’instruction Ptr->tracer( ) active la méthode tracer de la classe figure. =>
Vision utilisateur Tracé du rectangle Liaison dynamique des fonctionsFonctions 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( ); virtual La fonction tracer est virtuelle. Par conséquent, l’instruction Ptr->tracer( ); active la méthode associée au type dynamique de *ptr. => virtual
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).
Les fonctions virtuelles • 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é.
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. On ne peut pas tracer une figure, on tracera un carré, un cercle …=> la méthode tracer est virtuelle pure Une classe qui comprend une fonction virtuelle pure et qui ne l’implémente pas est une classe abstraite. class figure { public : void tracer (void) ; }; virtual =0 //fonction virtuelle pure
Classe abstraite • SYNTAXE : on indique qu’une méthode virtuelle est pure en ajoutant =0 en fin de spécification. class figure { public : void tracer (void) ; }; Une classe qui comprend une fonction virtuelle pure et qui ne l’implémente pas est une classe abstraite. virtual =0 //fonction virtuelle pure
Vision utilisateur //illégal //illégal UTILISATION D’UNE CLASSE ABSTRAITE class figure { public : virtualvoid tracer (void) =0; //fonction virtuelle pure }; figure F; figure* Ptr; Ptr = new figure; // légal L’instantiation de la classe figure n’a pas de sens. On en peut déclarer que des pointeurs sur figure. D ’une façon générale : L’instantiation d ’une classe abstraite n’a pas de sens. Elle est refusée à la compilation On en peut déclarer que des pointeurs sur une classe abstraite.