66
Programmation Orientée Objet en C++ ( Emanuel Aldea <[email protected]> http://hebergement.u-psud.fr/emi M1-E3A

Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Embed Size (px)

Citation preview

Page 1: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Programmation Orientée Objet en C++ (

Emanuel Aldea <[email protected]>http://hebergement.u-psud.fr/emi

M1-E3A

Page 2: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Troisième chapitre

L’héritage

Page 3: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

L’héritage

Déclaration :• La déclaration d’une classe peut faire intervenir une clause d’héritage

d’une ou plusieurs autres classes :class Enfant : public Parent1 , protected Parent2

{

char c;

...

};

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (3/22)

Page 4: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

L’héritage

Déclaration :• La déclaration d’une classe peut faire intervenir une clause d’héritage

d’une ou plusieurs autres classes :class Enfant : public Parent1 , protected Parent2

{

char c;

...

};

• La classe enfant hérite tous les membres des classes parents. La syntaxe

d’accès de l’intérieur ou de l’extérieur reste la même

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (3/22)

Page 5: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

L’héritage

Déclaration :• La déclaration d’une classe peut faire intervenir une clause d’héritage

d’une ou plusieurs autres classes :class Enfant : public Parent1 , protected Parent2

{

char c;

...

};

• La classe enfant hérite tous les membres des classes parents. La syntaxe

d’accès de l’intérieur ou de l’extérieur reste la même

• Il est interdit d’hériter de soi-même

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (3/22)

Page 6: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

L’héritage

Déclaration :• La déclaration d’une classe peut faire intervenir une clause d’héritage

d’une ou plusieurs autres classes :class Enfant : public Parent1 , protected Parent2

{

char c;

...

};

• La classe enfant hérite tous les membres des classes parents. La syntaxe

d’accès de l’intérieur ou de l’extérieur reste la même

• Il est interdit d’hériter de soi-même

int cntr float x

Parent1 Parent2

char c

Enfant

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (3/22)

Page 7: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

L’intérêt de l’héritage

Objectifs et idée générale

• étendre la fonctionnalité des classes déjà existantes : uneinstance de la classe Enfant est au même temps un objetde type Parent1 et un objet de type Parent2, en ayant enplus d’autres membres et méthodes

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (4/22)

Page 8: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

L’intérêt de l’héritage

Objectifs et idée générale

• étendre la fonctionnalité des classes déjà existantes : uneinstance de la classe Enfant est au même temps un objetde type Parent1 et un objet de type Parent2, en ayant enplus d’autres membres et méthodes

• réutilisation du code : la classe dérivée Enfant hérite tousles membres et méthodes des classes de base

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (4/22)

Page 9: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

L’intérêt de l’héritage

Objectifs et idée générale

• étendre la fonctionnalité des classes déjà existantes : uneinstance de la classe Enfant est au même temps un objetde type Parent1 et un objet de type Parent2, en ayant enplus d’autres membres et méthodes

• réutilisation du code : la classe dérivée Enfant hérite tousles membres et méthodes des classes de base

• réutilisation du code : l’héritage encourage le programmeurà s’appuyer sur du code déjà testé et de très bonne qualité, etempêche la multiplication inutile de code dans un projet

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (4/22)

Page 10: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

L’intérêt de l’héritage

Objectifs et idée générale

• étendre la fonctionnalité des classes déjà existantes : uneinstance de la classe Enfant est au même temps un objetde type Parent1 et un objet de type Parent2, en ayant enplus d’autres membres et méthodes

• réutilisation du code : la classe dérivée Enfant hérite tousles membres et méthodes des classes de base

• réutilisation du code : l’héritage encourage le programmeurà s’appuyer sur du code déjà testé et de très bonne qualité, etempêche la multiplication inutile de code dans un projet

• un pointeur vers une instance Enfant peut être convertidans un pointeur vers une instance Parent, et utilisé danscette forme. L’opération inverse n’est valide que si l’objetpointé est réellement de type Enfant à l’origine.

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (4/22)

Page 11: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage monoparental

Caractéristiques

• le cas illustratif de base (et le plus fréquent)

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (5/22)

Page 12: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage monoparental

Caractéristiques

• le cas illustratif de base (et le plus fréquent)

• intérêt : les méthodes de la classe dérivée Enfant peuvent exploiter les

attributs et méthodes de la classe de base Parent

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (5/22)

Page 13: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage monoparental

Caractéristiques

• le cas illustratif de base (et le plus fréquent)

• intérêt : les méthodes de la classe dérivée Enfant peuvent exploiter les

attributs et méthodes de la classe de base Parent

• class Enfant : public Parent

{

...

};

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (5/22)

Page 14: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage multiple

Caractéristiques• un cas fréquent également : illustration des hiérarchies des classes

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (6/22)

Page 15: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage multiple

Caractéristiques• un cas fréquent également : illustration des hiérarchies des classes

• intérêt : les classes dérivées sont des instances spécialisées des classes de base, et la spécialisation peut se faire en

cascade

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (6/22)

Page 16: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage multiple

Caractéristiques• un cas fréquent également : illustration des hiérarchies des classes

• intérêt : les classes dérivées sont des instances spécialisées des classes de base, et la spécialisation peut se faire en

cascade

• class Parent1 : public GParent1

{

...

};

class Enfant : public Parent1

{

...

};

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (6/22)

Page 17: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage multi-parental

Cas 1 : parents indépendants• un cas moins fréquent : illustration des hiérarchies des classes

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (7/22)

Page 18: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage multi-parental

Cas 1 : parents indépendants• un cas moins fréquent : illustration des hiérarchies des classes

• intérêt : certaines classes héritent des fonctionnalités nécessaires à partir de deux classes de base indépendantes

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (7/22)

Page 19: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage multi-parental

Cas 1 : parents indépendants• un cas moins fréquent : illustration des hiérarchies des classes

• intérêt : certaines classes héritent des fonctionnalités nécessaires à partir de deux classes de base indépendantes

• à éviter si possible : il y a des pratiques recommandées qui font éviter dans la plupart des cas ce type de héritage

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (7/22)

Page 20: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage multi-parental

Cas 1 : parents indépendants• un cas moins fréquent : illustration des hiérarchies des classes

• intérêt : certaines classes héritent des fonctionnalités nécessaires à partir de deux classes de base indépendantes

• à éviter si possible : il y a des pratiques recommandées qui font éviter dans la plupart des cas ce type de héritage

• class Enfant : public Parent1, public Parent2

{

...

};

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (7/22)

Page 21: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage multi-parental

Cas 2 : parents ayant une classe de base commune• à éviter absolument : des ambiguïtés graves car la classe de base commune aux parents est dupliquée à l’intérieur de

l’objet Enfant

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (8/22)

Page 22: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage multi-parental

Cas 2 : parents ayant une classe de base commune• à éviter absolument : des ambiguïtés graves car la classe de base commune aux parents est dupliquée à l’intérieur de

l’objet Enfant

• situation connue sous le nom du diamant de la mort

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (8/22)

Page 23: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage multi-parental

Cas 2 : parents ayant une classe de base commune• à éviter absolument : des ambiguïtés graves car la classe de base commune aux parents est dupliquée à l’intérieur de

l’objet Enfant

• situation connue sous le nom du diamant de la mort

• class Parent1 : public GParent

{ ... };

class Parent2 : public GParent

{ ... };

class Enfant : public Parent1, public Parent2

{ ... };

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (8/22)

Page 24: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage multi-parental

Première solution pour éviter le diamant de la mort• déclarer le héritage du GParent comme virtual

• class Parent1 : virtual public GParent

{ ... };

class Parent2 : virtual public GParent

{ ... };

class Enfant : public Parent1, public Parent2

{ ... };

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (9/22)

Page 25: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage multi-parental

Première solution pour éviter le diamant de la mort• déclarer le héritage du GParent comme virtual

• class Parent1 : virtual public GParent

{ ... };

class Parent2 : virtual public GParent

{ ... };

class Enfant : public Parent1, public Parent2

{ ... };

• on appelle automatiquement le constructeur sans paramètres du GParent (s’il n’existe pas : erreur !)

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (9/22)

Page 26: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage multi-parental

Deuxième solution pour éviter le diamant de la mort

• à la place de dire que le copieur est un scanner + printer

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (10/22)

Page 27: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage multi-parental

Deuxième solution pour éviter le diamant de la mort

• à la place de dire que le copieur est un scanner + printer• class ComplexObj

{

Parent1 scanner;

Parent2 printer;

};

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (10/22)

Page 28: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage multi-parental

Deuxième solution pour éviter le diamant de la mort

• à la place de dire que le copieur est un scanner + printer• class ComplexObj

{

Parent1 scanner;

Parent2 printer;

};

• composition : designer une classe complexe conteneur

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (10/22)

Page 29: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage - vie des objets

Les constructeurs / destructeurs• Syntaxe d’appel des constructeurs des classes hérités : la

même que pour les attributs

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (11/22)

Page 30: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage - vie des objets

Les constructeurs / destructeurs• Syntaxe d’appel des constructeurs des classes hérités : la

même que pour les attributs

• La classe Enfant peut appeler explicitement (sans êtreobligée) tout constructeur non - privé des classes parents (unseul par classe héritée)

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (11/22)

Page 31: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage - vie des objets

Les constructeurs / destructeurs• Syntaxe d’appel des constructeurs des classes hérités : la

même que pour les attributs

• La classe Enfant peut appeler explicitement (sans êtreobligée) tout constructeur non - privé des classes parents (unseul par classe héritée)

• L’appel des constructeurs des grand-parents : interdit oudangereux (en fonction de compilateur)

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (11/22)

Page 32: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage - vie des objets

Les constructeurs / destructeurs• Syntaxe d’appel des constructeurs des classes hérités : la

même que pour les attributs

• La classe Enfant peut appeler explicitement (sans êtreobligée) tout constructeur non - privé des classes parents (unseul par classe héritée)

• L’appel des constructeurs des grand-parents : interdit oudangereux (en fonction de compilateur)

• L’ordre d’appel effectif = l’ordre de déclaration

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (11/22)

Page 33: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage - vie des objets

Les constructeurs / destructeurs• Syntaxe d’appel des constructeurs des classes hérités : la

même que pour les attributs

• La classe Enfant peut appeler explicitement (sans êtreobligée) tout constructeur non - privé des classes parents (unseul par classe héritée)

• L’appel des constructeurs des grand-parents : interdit oudangereux (en fonction de compilateur)

• L’ordre d’appel effectif = l’ordre de déclaration

• Destruction : le compilateur appelle, après le corps dudestructeur, tous les destructeurs des classes héritées

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (11/22)

Page 34: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage - visibilité des membres

Cas d’usage en héritage multiple

• Par défaut tous les attributs et les méthodes héritées sontvisibles à la classe Enfant (en respectant les droitsd’accès). Mais on peut avoir des situations ambiguës.

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (12/22)

Page 35: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage - visibilité des membres

Cas d’usage en héritage multiple

• Par défaut tous les attributs et les méthodes héritées sontvisibles à la classe Enfant (en respectant les droitsd’accès). Mais on peut avoir des situations ambiguës.

• Visibilité cachée par un membre de l’enfant

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (12/22)

Page 36: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage - visibilité des membres

Cas d’usage en héritage multiple

• Par défaut tous les attributs et les méthodes héritées sontvisibles à la classe Enfant (en respectant les droitsd’accès). Mais on peut avoir des situations ambiguës.

• Visibilité cachée par un membre de l’enfant

• Ambiguïté entre deux membres portant le même nom maisse trouvant dans deux sous-objets différents

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (12/22)

Page 37: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage - visibilité des membres

Cas d’usage en héritage multiple

• Par défaut tous les attributs et les méthodes héritées sontvisibles à la classe Enfant (en respectant les droitsd’accès). Mais on peut avoir des situations ambiguës.

• Visibilité cachée par un membre de l’enfant

• Ambiguïté entre deux membres portant le même nom maisse trouvant dans deux sous-objets différents

• Solution : opérateur de résolution de portée :: versl’espace du sous-objet

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (12/22)

Page 38: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage - accès

• L’accès aux membres hérités est soumis aux droits d’accèsrésultant de l’héritage

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (13/22)

Page 39: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage - accès

• L’accès aux membres hérités est soumis aux droits d’accèsrésultant de l’héritage

• Sans le préciser, par défaut, l’héritage est de type private

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (13/22)

Page 40: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage - accès

• L’accès aux membres hérités est soumis aux droits d’accèsrésultant de l’héritage

• Sans le préciser, par défaut, l’héritage est de type private

• L’héritage ne fait que renforcer les contraintes d’accès (voir letableau des droits)

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (13/22)

Page 41: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage - accès

• L’accès aux membres hérités est soumis aux droits d’accèsrésultant de l’héritage

• Sans le préciser, par défaut, l’héritage est de type private

• L’héritage ne fait que renforcer les contraintes d’accès (voir letableau des droits)

• Exception : les opérateurs membres sont toujours hérités enmode public (il est impossible de restreindre leur accès)

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (13/22)

Page 42: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Héritage - accès

• L’accès aux membres hérités est soumis aux droits d’accèsrésultant de l’héritage

• Sans le préciser, par défaut, l’héritage est de type private

• L’héritage ne fait que renforcer les contraintes d’accès (voir letableau des droits)

• Exception : les opérateurs membres sont toujours hérités enmode public (il est impossible de restreindre leur accès)

Accès initial H. public H. protected H. private

public public protected privateprotected protected protected privateprivate pas d’accès pas d’accès pas d’accès

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (13/22)

Page 43: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Surcharge et polymorphisme

• En C++ le polymorphisme est la capacité à donner le mêmenom à des fonctions / méthodes / opérateurs qui ont uncomportement diffèrent en fonction des paramètres, desobjets et du contexte dans lequel on les emploie.

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (14/22)

Page 44: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Surcharge et polymorphisme

• En C++ le polymorphisme est la capacité à donner le mêmenom à des fonctions / méthodes / opérateurs qui ont uncomportement diffèrent en fonction des paramètres, desobjets et du contexte dans lequel on les emploie.

• Exemples en C “classique" : les opérateurs + - / * = < >

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (14/22)

Page 45: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Surcharge et polymorphisme

• En C++ le polymorphisme est la capacité à donner le mêmenom à des fonctions / méthodes / opérateurs qui ont uncomportement diffèrent en fonction des paramètres, desobjets et du contexte dans lequel on les emploie.

• Exemples en C “classique" : les opérateurs + - / * = < >

• Comportement différent réel / entier / signé etc.

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (14/22)

Page 46: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Types de polymorphisme

• Polymorphisme statique de surcharge

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (15/22)

Page 47: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Types de polymorphisme

• Polymorphisme statique de surcharge

• on peut utiliser un objet enfant à la place du parent parce qu’il le

contient

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (15/22)

Page 48: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Types de polymorphisme

• Polymorphisme statique de surcharge

• on peut utiliser un objet enfant à la place du parent parce qu’il le

contient

• deux versions : statique et dynamique

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (15/22)

Page 49: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Types de polymorphisme

• Polymorphisme statique de surcharge

• on peut utiliser un objet enfant à la place du parent parce qu’il le

contient

• deux versions : statique et dynamique

• Polymorphisme statique : comportement connu et déterminé à la

compilation

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (15/22)

Page 50: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Types de polymorphisme

• Polymorphisme statique de surcharge

• on peut utiliser un objet enfant à la place du parent parce qu’il le

contient

• deux versions : statique et dynamique

• Polymorphisme statique : comportement connu et déterminé à la

compilation

• Polymorphisme dynamique : comportement inconnu à la compilation et

déterminé à l’exécution, par l’objet

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (15/22)

Page 51: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Polymorphisme d’héritage statique

• Une classe enfant peut surcharger (redéfinir) le corps d’uneméthode du parent à la condition de respecter le mêmeprototype (même signature)

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (16/22)

Page 52: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Polymorphisme d’héritage statique

• Une classe enfant peut surcharger (redéfinir) le corps d’uneméthode du parent à la condition de respecter le mêmeprototype (même signature)

• Les nouvelles méthodes de l’enfant appelleront par défaut laméthode surchargée alors que les méthodes héritéesappelleront la méthode initiale du parent

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (16/22)

Page 53: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Polymorphisme d’héritage statique

class Parent

{ // ...

const char* GetName () {return "Parent";}

void AffName () { printf ("%s \ n", GetName ());}

};

class Enfant : public Parent

{ // ...

const char* GetName () {return "Enfant";}

void Aff2Name() { printf ("%s \ n", GetName ());}

void Aff3Name() { printf ("%s \ n",Parent:: GetName ());}

void Aff4Name() { printf ("%s \ n", AffName ());}

};

void main()

{ Enfant enf1, *penf2=new Enfant;

Parent par1;

printf ("%s \ n",enf1. GetName ()); //"Enfant"

printf ("%s \ n",penf2 - > GetName ()); //"Enfant"

printf ("%s \ n",(Parent*)penf2 - > GetName ()); //"Parent"

printf ("%s \ n",par1. GetName ()); //"Parent"

printf ("%s \ n",((Parent*)&enf1) - > GetName ());//"Parent"

enf1. AffName (); //"Parent"

penf2 - >Aff2Name(); //"Enfant"

enf1.Aff3Name(); //"Parent"

((Parent)enf1). AffName (); //"Parent"

enf1.Aff4Name(); //"Parent"

};

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (17/22)

Page 54: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Polymorphisme d’héritage dynamique

• Le PHD n’est actif que pour les appels directs , sansopérateur de résolution de portée

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (18/22)

Page 55: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Polymorphisme d’héritage dynamique

• Le PHD n’est actif que pour les appels directs , sansopérateur de résolution de portée

• En utilisant le qualificatif virtuel dans la déclaration deprototype d’une méthode du parent, la surcharge devienteffective aussi pour les méthodes du parent héritées parl’enfant

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (18/22)

Page 56: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Polymorphisme d’héritage dynamique

• Le PHD n’est actif que pour les appels directs , sansopérateur de résolution de portée

• En utilisant le qualificatif virtuel dans la déclaration deprototype d’une méthode du parent, la surcharge devienteffective aussi pour les méthodes du parent héritées parl’enfant

• La redéfinition remplace la méthode des parents

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (18/22)

Page 57: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Polymorphisme d’héritage dynamique

• Le PHD n’est actif que pour les appels directs , sansopérateur de résolution de portée

• En utilisant le qualificatif virtuel dans la déclaration deprototype d’une méthode du parent, la surcharge devienteffective aussi pour les méthodes du parent héritées parl’enfant

• La redéfinition remplace la méthode des parents

• Le caractère virtuel d’une méthode est défini dans la classeparent et il ne change plus à travers les héritages

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (18/22)

Page 58: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Polymorphisme d’héritage dynamique

• La version initiale de la méthode virtuelle surchargée restevisible aux parents et aux enfants seulement parl’intermédiaire de l’opérateur de portée Parent:: Methode()

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (19/22)

Page 59: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Polymorphisme d’héritage dynamique

• La version initiale de la méthode virtuelle surchargée restevisible aux parents et aux enfants seulement parl’intermédiaire de l’opérateur de portée Parent:: Methode()

• L’adresse d’une méthode virtuelle est un attribut statiquecaché (tables virtuelles) de la classe, tout appel direct passepar cette adresse

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (19/22)

Page 60: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Polymorphisme d’héritage dynamique

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (20/22)

Page 61: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Polymorphisme d’héritage dynamique

class Parent

{ // ...

virtual const char* GetName () {return "Parent";}

void AffName () { printf ("%s \ n", GetName ());}

};

class Enfant : public Parent

{ // ...

const char* GetName () {return "Enfant";}

void Aff2Name() { printf ("%s \ n", GetName ());}

void Aff3Name() { printf ("%s \ n",Parent:: GetName ());}

void Aff4Name() { printf ("%s \ n", AffName ());}

};

void main()

{ Enfant enf1, *penf2=new Enfant;

Parent par1;

printf ("%s \ n",enf1. GetName ()); //"Enfant"

printf ("%s \ n",penf2 - > GetName ()); //"Enfant"

printf ("%s \ n",(Parent*)penf2 - > GetName ()); //"Enfant"

printf ("%s \ n",par1. GetName ()); //"Parent"

printf ("%s \ n",((Parent*)&enf1) - > GetName ());//"Enfant"

enf1. AffName (); //"Enfant"

penf2 - >Aff2Name(); //"Enfant"

enf1.Aff3Name(); //"Parent"

((Parent)enf1). AffName (); //"Parent"

enf1.Aff4Name(); //"Enfant"

};

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (21/22)

Page 62: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Polymorphisme d’héritage dynamique

• La classe parent peut ne pas définir la méthode virtuelle :alors elle devient une méthode virtuelle pureclass Parent { // ...

virtual const char* GetName () =0 ;

};

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (22/22)

Page 63: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Polymorphisme d’héritage dynamique

• La classe parent peut ne pas définir la méthode virtuelle :alors elle devient une méthode virtuelle pureclass Parent { // ...

virtual const char* GetName () =0 ;

};

• Concrètement, l’adresse de la méthode (dans la tablevirtuelle) est initialisée à zéro

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (22/22)

Page 64: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Polymorphisme d’héritage dynamique

• La classe parent peut ne pas définir la méthode virtuelle :alors elle devient une méthode virtuelle pureclass Parent { // ...

virtual const char* GetName () =0 ;

};

• Concrètement, l’adresse de la méthode (dans la tablevirtuelle) est initialisée à zéro

• Les héritiers ont l’obligation de définir cette méthode, enrespectant le prototype

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (22/22)

Page 65: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Polymorphisme d’héritage dynamique

• La classe parent peut ne pas définir la méthode virtuelle :alors elle devient une méthode virtuelle pureclass Parent { // ...

virtual const char* GetName () =0 ;

};

• Concrètement, l’adresse de la méthode (dans la tablevirtuelle) est initialisée à zéro

• Les héritiers ont l’obligation de définir cette méthode, enrespectant le prototype

• Base abstraite : une classe qui a au moins une méthodevirtuelle pure ; elle ne peut pas avoir d’instances

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (22/22)

Page 66: Programmation Orientée Objet en C++hebergement.u-psud.fr/emi/443/cours4-heritage-poly-eleves-gs.pdf · Cas 2 : parents ayant une classe de base commune • à éviter absolument

Polymorphisme d’héritage dynamique

• La classe parent peut ne pas définir la méthode virtuelle :alors elle devient une méthode virtuelle pureclass Parent { // ...

virtual const char* GetName () =0 ;

};

• Concrètement, l’adresse de la méthode (dans la tablevirtuelle) est initialisée à zéro

• Les héritiers ont l’obligation de définir cette méthode, enrespectant le prototype

• Base abstraite : une classe qui a au moins une méthodevirtuelle pure ; elle ne peut pas avoir d’instances

• Une base abstraite ne sert que pour être héritée : c’est lepoint de départ d’une famille de classes, par exemple

E. Aldea (M1-E3A) POO C++ Chap III : L’héritage (22/22)