![Page 1: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/1.jpg)
Fabio [email protected]
Programmation Orientée Objet en C++Programmation Orientée Objet en C++
13ème Partie: Héritage Multiple13ème Partie: Héritage Multiple
![Page 2: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/2.jpg)
© 1997-2003 Fabio HERNANDEZ449POO en C++: Héritage Multiple
Vue d'EnsembleVue d'Ensemble
Notions de base Types, variables, opérateursContrôle d'exécutionFonctionsMémoire dynamiqueQualité du logicielEvolution du modèle objet Objets et classesFonctions membresClasses génériquesHéritagePolymorphismeHéritage multipleEntrée/sortie
![Page 3: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/3.jpg)
© 1997-2003 Fabio HERNANDEZ450POO en C++: Héritage Multiple
Table des MatièresTable des Matières
MotivationExempleHéritage et AmbiguïtéHéritage RépétéRésumé
![Page 4: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/4.jpg)
© 1997-2003 Fabio HERNANDEZ451POO en C++: Héritage Multiple
MotivationMotivation
Nous avons étudié l'héritage comme un mécanisme permettant d'exprimer les caractéristiques et le comportement communs existants dans des groupes de structures similaires mais aussi leurs spécificitésLes exemples présentés illustraient le cas de l'héritage simple:une classe héritant d'une seule classe de baseContrairement à d'autres langages OO, C++ offre la possibilité à une classe d'hériter de plusieurs classes de baseCe mécanisme est appelé héritage multiple
![Page 5: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/5.jpg)
© 1997-2003 Fabio HERNANDEZ452POO en C++: Héritage Multiple
Motivation (suite)Motivation (suite)
Figure
OpenFigure ClosedFigure
Polygon Ellipse
CircleTriangle Rectangle
Square
Segment Polyline
...
![Page 6: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/6.jpg)
© 1997-2003 Fabio HERNANDEZ453POO en C++: Héritage Multiple
Motivation (suite)Motivation (suite)
Les caractéristiques d'une figure "dessinable" peuvent être modélisées comme une classe
Drawable
color_: ColorlineType_: LineTypelineThickness_: LineThickness
draw: boolsetColor:boolgetColor: ColorsetLineType: boolgetLineType: LineTypesetLineThickness: boolgetLineThickness: LineThickness
![Page 7: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/7.jpg)
© 1997-2003 Fabio HERNANDEZ454POO en C++: Héritage Multiple
Motivation (suite)Motivation (suite)
Un polygone dessinable peut hériter de deux classes
PolygonDrawable
DrawablePolygon
![Page 8: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/8.jpg)
© 1997-2003 Fabio HERNANDEZ455POO en C++: Héritage Multiple
Contrôle d'AvancementContrôle d'Avancement
MotivationExempleHéritage et AmbiguïtéHéritage RépétéRésumé
![Page 9: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/9.jpg)
© 1997-2003 Fabio HERNANDEZ456POO en C++: Héritage Multiple
ClasseClasse DrawableDrawable
class Drawable {
public:
// Constructors/Destructor
Drawable(Color color, LineType type);
virtual ~Drawable();
// Modifiersvirtual bool draw() = 0;bool setColor(Color color);bool setLineType(LineType type);bool setLineThickness(LineThickness thickness);
![Page 10: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/10.jpg)
© 1997-2003 Fabio HERNANDEZ457POO en C++: Héritage Multiple
ClasseClasse DrawableDrawable (suite)(suite)
// SelectorsLineType getLineType() const;LineThickness getLineThickness() const;Color getColor() const;
private:
// Data members
Color color_;
LineType lineType_;
LineThickness lineThickness_;
};
![Page 11: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/11.jpg)
© 1997-2003 Fabio HERNANDEZ458POO en C++: Héritage Multiple
Rappel: Classe Rappel: Classe RectangleRectangle
class Rectangle : public Polygon {
public:
// Constructors/Destructor
Rectangle(const Point& origin,
float side1,
float side2);
virtual ~Rectangle();
// Modifiersvirtual void translate(float horizontal,
float vertical);virtual void rotate(float angle);...
![Page 12: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/12.jpg)
© 1997-2003 Fabio HERNANDEZ459POO en C++: Héritage Multiple
Rappel: Classe Rappel: Classe Rectangle Rectangle (suite)(suite)
// Selectorsvirtual float perimeter() const;virtual float area() const;virtual bool isInside(const Point& aPoint) const;float diagonal() const;...
private:
// Data members
float side1_;
float side2_;
Point origin_;
};
![Page 13: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/13.jpg)
© 1997-2003 Fabio HERNANDEZ460POO en C++: Héritage Multiple
ClasseClasse DrawableRectangleDrawableRectangle
class DrawableRectangle : public Rectangle,
public Drawable {
public:
// Constructors/Destructor
DrawableRectangle(const Point& origin,
float side1,
float side2);
virtual ~DrawableRectangle();
// Modifiers
virtual bool draw();
};
Héritage de deux classes de base
![Page 14: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/14.jpg)
© 1997-2003 Fabio HERNANDEZ461POO en C++: Héritage Multiple
DrawableRectangleDrawableRectangle : implémentation: implémentation
L'implémentation du constructeur serait
DrawableRectangle::DrawableRectangle(const Point& origin,
float side1,
float side2)
: Rectangle(origin, side1, side2),
Drawable(Red, Solid)
{// Nothing more to do
}Appel aux constructeur
des classes de base, avec les arguments
nécessaires
![Page 15: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/15.jpg)
© 1997-2003 Fabio HERNANDEZ462POO en C++: Héritage Multiple
DrawableRectangleDrawableRectangle : implémentation (suite): implémentation (suite)
Les constructeurs des classes de base sont appelés avant le constructeur de la classe dérivée, dans l'ordre de déclaration des classes de base dans l'interface de la classe, et ce indépendamment de la liste d'initialisation
d'abord le constructeur de Rectangle et après celui de Drawable dans cet exemple
Dans la liste d'initialisation, il n'est pas nécessaire de spécifier le constructeur d'une classe de base qui ne définit pas un constructeur ou qui en définit un par défautUne classe de base doit être initialisée avec la liste d'arguments attendue par son constructeurLes destructeurs des classes de base sont appelés dans l'ordre inverse de celui des constructeurs
![Page 16: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/16.jpg)
© 1997-2003 Fabio HERNANDEZ463POO en C++: Héritage Multiple
DrawableRectangleDrawableRectangle : implémentation (suite): implémentation (suite)
Nous devons fournir une implémentation pour la méthode abstraite draw
bool DrawableRectangle::draw(){
// Do whatever is necessary to draw a rectangle.// Here we can use inherited methods getColor(),// getLineType(), etc.
}
![Page 17: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/17.jpg)
© 1997-2003 Fabio HERNANDEZ464POO en C++: Héritage Multiple
DrawableRectangleDrawableRectangle : utilisation: utilisation
Les objets de cette classe offrent les services hérités de deux classes de base
DrawableRectangle drect(Point(10.0, 45.0), 14.0, 15.0);
// Compute its perimeter
float perimeter = drect.perimeter();
// Rectangle::perimeter
// Change its color and draw it
drect.setColor(Green); // Drawable::setColor
drect.draw(); // Drawable::draw
![Page 18: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/18.jpg)
© 1997-2003 Fabio HERNANDEZ465POO en C++: Héritage Multiple
Contrôle d'AvancementContrôle d'Avancement
MotivationExempleHéritage et AmbiguïtéHéritage RépétéRésumé
![Page 19: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/19.jpg)
© 1997-2003 Fabio HERNANDEZ466POO en C++: Héritage Multiple
Héritage et AmbiguïtéHéritage et Ambiguïté
Une classe dans une hiérarchie de classes peut hériter deux ou plusieurs méthodes ou attributs avec la même signature
class Base1 {
public:
// Constructors/Destructor...// Selectorsvoid print() const;
private:// Data members...
};
![Page 20: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/20.jpg)
© 1997-2003 Fabio HERNANDEZ467POO en C++: Héritage Multiple
Héritage et Ambiguïté (suite)Héritage et Ambiguïté (suite)
class Base2 {
public:
// Constructors/Destructor...// Selectorsvoid print() const;
private:// Data members...
};
![Page 21: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/21.jpg)
© 1997-2003 Fabio HERNANDEZ468POO en C++: Héritage Multiple
Héritage et Ambiguïté (suite)Héritage et Ambiguïté (suite)
class Derived: public Base1,
public Base2 {
public:
// Constructors/Destructor...// Selectors...
private:// Data members...
};
![Page 22: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/22.jpg)
© 1997-2003 Fabio HERNANDEZ469POO en C++: Héritage Multiple
Héritage et Ambiguïté (suite)Héritage et Ambiguïté (suite)
Le compilateur signale une erreur lorsqu'il ne peut pas lever l'ambiguïté
Derived d;
d.print(); // ERROR: Base1::print() or Base2::print() ?
C'est au programmeur de spécifier sans ambiguïté la méthode souhaitéeDeux façons
avec l'opérateur de portéed.Base1::print(); // OK: Base1::print() is called
en définissant la méthode Derived::print()
![Page 23: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/23.jpg)
© 1997-2003 Fabio HERNANDEZ470POO en C++: Héritage Multiple
Héritage et Ambiguïté (suite)Héritage et Ambiguïté (suite)
class Derived: public Base1,
public Base2 {
public:
// Constructors/Destructor...// Selectorsvoid print() const;
private:// Data members...
};
Cache Base1::print()
et Base2::print()
![Page 24: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/24.jpg)
© 1997-2003 Fabio HERNANDEZ471POO en C++: Héritage Multiple
Héritage et Ambiguïté (suite)Héritage et Ambiguïté (suite)
Il n'y a plus d'ambiguïtéDerived d;
d.print(); // OK: Derived::print() is called
L'implémentation de Derived::print() peut utiliser la méthode print() des classes de base
void Derived::print() const
{
Base1::print();
Base2::print();
}
![Page 25: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/25.jpg)
© 1997-2003 Fabio HERNANDEZ472POO en C++: Héritage Multiple
Contrôle d'AvancementContrôle d'Avancement
MotivationExempleHéritage et AmbiguïtéHéritage RépétéRésumé
![Page 26: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/26.jpg)
© 1997-2003 Fabio HERNANDEZ473POO en C++: Héritage Multiple
Héritage RépétéHéritage Répété
Dans certains cas, une classe peut hériter plus d'une fois d'unemême classe de base dans une hiérarchie
StudentTeacher
TeachingAssistant
Employee
![Page 27: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/27.jpg)
© 1997-2003 Fabio HERNANDEZ474POO en C++: Héritage Multiple
Héritage Répété (suite)Héritage Répété (suite)
class Employee {...
};class Teacher: public Employee {
...};class Student: public Employee {
...};class TeachingAssistant: public Teacher,
public Student {...
};
Un objet de la classe TeachingAssistant contiendra deux fois les données héritées de la classe Employee: une fois par l'héritage de la classe Teacher et une autre par la classeStudent
![Page 28: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/28.jpg)
© 1997-2003 Fabio HERNANDEZ475POO en C++: Héritage Multiple
Héritage Répété (suite)Héritage Répété (suite)
Il est possible de n'avoir qu'une occurrence des membres de la classe de base, en utilisant l'héritage virtuel
class Employee {...
};class Teacher: virtual public Employee {
...};class Student: virtual public Employee {
...};class TeachingAssistant: public Teacher,
public Student {...
}; Une seule occurrence des données de la classe Employee
dans TeachingAssistant
![Page 29: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/29.jpg)
© 1997-2003 Fabio HERNANDEZ476POO en C++: Héritage Multiple
Contrôle d'AvancementContrôle d'Avancement
MotivationExempleHéritage et AmbiguïtéHéritage RépétéRésumé
![Page 30: Partie 13: Héritage Multiple — Programmation orientée objet en C++](https://reader038.vdocuments.pub/reader038/viewer/2022103114/555caf8dd8b42ab2358b51ef/html5/thumbnails/30.jpg)
© 1997-2003 Fabio HERNANDEZ477POO en C++: Héritage Multiple
RésuméRésumé
Contrairement à d'autres langages OO, en C++ une classe peut hériter directement de plusieurs classe de baseL'héritage peut provoquer des ambiguïtés qui doivent être levées par le programmeurL'héritage virtuel permet de n'avoir qu'une seule occurrence d'une classe de base dans une classe dérivée, en présence d'héritage répété