Más contenido relacionado
La actualidad más candente (20)
Similar a Partie 13: Héritage Multiple — Programmation orientée objet en C++ (13)
Partie 13: Héritage Multiple — Programmation orientée objet en C++
- 2. Vue d'Ensemble
Notions de base
Types, variables, opérateurs
Contrôle d'exécution
Fonctions
Mémoire dynamique
Qualité du logiciel
Evolution du modèle objet
Objets et classes
Fonctions membres
Classes génériques
Héritage
Polymorphisme
Héritage multiple
Entrée/sortie
POO en C++: Héritage Multiple 449 © 1997-2003 Fabio HERNANDEZ
- 3. Table des Matières
Motivation
Exemple
Héritage et Ambiguïté
Héritage Répété
Résumé
POO en C++: Héritage Multiple 450 © 1997-2003 Fabio HERNANDEZ
- 4. Motivation
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és
Les exemples présentés illustraient le cas de l'héritage simple:
une classe héritant d'une seule classe de base
Contrairement à d'autres langages OO, C++ offre la possibilité
à une classe d'hériter de plusieurs classes de base
Ce mécanisme est appelé héritage multiple
POO en C++: Héritage Multiple 451 © 1997-2003 Fabio HERNANDEZ
- 5. Motivation (suite)
Figure
OpenFigure ClosedFigure
Segment Polyline Polygon Ellipse
Triangle Rectangle ... Circle
Square
POO en C++: Héritage Multiple 452 © 1997-2003 Fabio HERNANDEZ
- 6. Motivation (suite)
Les caractéristiques d'une figure "dessinable" peuvent être
modélisées comme une classe
Drawable
color_: Color
lineType_: LineType
lineThickness_: LineThickness
draw: bool
setColor:bool
getColor: Color
setLineType: bool
getLineType: LineType
setLineThickness: bool
getLineThickness: LineThickness
POO en C++: Héritage Multiple 453 © 1997-2003 Fabio HERNANDEZ
- 7. Motivation (suite)
Un polygone dessinable peut hériter de deux classes
Drawable Polygon
DrawablePolygon
POO en C++: Héritage Multiple 454 © 1997-2003 Fabio HERNANDEZ
- 8. Contrôle d'Avancement
Motivation
Exemple
Héritage et Ambiguïté
Héritage Répété
Résumé
POO en C++: Héritage Multiple 455 © 1997-2003 Fabio HERNANDEZ
- 9. Classe Drawable
class Drawable {
public:
// Constructors/Destructor
Drawable(Color color, LineType type);
virtual ~Drawable();
// Modifiers
virtual bool draw() = 0;
bool setColor(Color color);
bool setLineType(LineType type);
bool setLineThickness(LineThickness thickness);
POO en C++: Héritage Multiple 456 © 1997-2003 Fabio HERNANDEZ
- 10. Classe Drawable (suite)
// Selectors
LineType getLineType() const;
LineThickness getLineThickness() const;
Color getColor() const;
private:
// Data members
Color color_;
LineType lineType_;
LineThickness lineThickness_;
};
POO en C++: Héritage Multiple 457 © 1997-2003 Fabio HERNANDEZ
- 11. Rappel: Classe Rectangle
class Rectangle : public Polygon {
public:
// Constructors/Destructor
Rectangle(const Point& origin,
float side1,
float side2);
virtual ~Rectangle();
// Modifiers
virtual void translate(float horizontal,
float vertical);
virtual void rotate(float angle);
...
POO en C++: Héritage Multiple 458 © 1997-2003 Fabio HERNANDEZ
- 12. Rappel: Classe Rectangle (suite)
// Selectors
virtual 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_;
};
POO en C++: Héritage Multiple 459 © 1997-2003 Fabio HERNANDEZ
- 13. Classe DrawableRectangle
class DrawableRectangle : public Rectangle,
public Drawable {
public: Héritage de deux
// Constructors/Destructor classes de base
DrawableRectangle(const Point& origin,
float side1,
float side2);
virtual ~DrawableRectangle();
// Modifiers
virtual bool draw();
};
POO en C++: Héritage Multiple 460 © 1997-2003 Fabio HERNANDEZ
- 14. DrawableRectangle : 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
POO en C++: Héritage Multiple 461 © 1997-2003 Fabio HERNANDEZ
- 15. DrawableRectangle : 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éfaut
Une classe de base doit être initialisée avec la liste
d'arguments attendue par son constructeur
Les destructeurs des classes de base sont appelés dans l'ordre
inverse de celui des constructeurs
POO en C++: Héritage Multiple 462 © 1997-2003 Fabio HERNANDEZ
- 16. DrawableRectangle : 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.
}
POO en C++: Héritage Multiple 463 © 1997-2003 Fabio HERNANDEZ
- 17. DrawableRectangle : 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
POO en C++: Héritage Multiple 464 © 1997-2003 Fabio HERNANDEZ
- 18. Contrôle d'Avancement
Motivation
Exemple
Héritage et Ambiguïté
Héritage Répété
Résumé
POO en C++: Héritage Multiple 465 © 1997-2003 Fabio HERNANDEZ
- 19. 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
...
// Selectors
void print() const;
private:
// Data members
...
};
POO en C++: Héritage Multiple 466 © 1997-2003 Fabio HERNANDEZ
- 20. Héritage et Ambiguïté (suite)
class Base2 {
public:
// Constructors/Destructor
...
// Selectors
void print() const;
private:
// Data members
...
};
POO en C++: Héritage Multiple 467 © 1997-2003 Fabio HERNANDEZ
- 21. Héritage et Ambiguïté (suite)
class Derived: public Base1,
public Base2 {
public:
// Constructors/Destructor
...
// Selectors
...
private:
// Data members
...
};
POO en C++: Héritage Multiple 468 © 1997-2003 Fabio HERNANDEZ
- 22. 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ée
Deux façons
avec l'opérateur de portée
d.Base1::print(); // OK: Base1::print() is called
en définissant la méthode Derived::print()
POO en C++: Héritage Multiple 469 © 1997-2003 Fabio HERNANDEZ
- 23. Héritage et Ambiguïté (suite)
class Derived: public Base1,
public Base2 {
public:
// Constructors/Destructor
...
// Selectors
Cache
Base1::print()
void print() const;
et
Base2::print()
private:
// Data members
...
};
POO en C++: Héritage Multiple 470 © 1997-2003 Fabio HERNANDEZ
- 24. 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();
}
POO en C++: Héritage Multiple 471 © 1997-2003 Fabio HERNANDEZ
- 25. Contrôle d'Avancement
Motivation
Exemple
Héritage et Ambiguïté
Héritage Répété
Résumé
POO en C++: Héritage Multiple 472 © 1997-2003 Fabio HERNANDEZ
- 26. Héritage Répété
Dans certains cas, une classe peut hériter plus d'une fois d'une
même classe de base dans une hiérarchie
Employee
Teacher Student
TeachingAssistant
POO en C++: Héritage Multiple 473 © 1997-2003 Fabio HERNANDEZ
- 27. 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 classe
Student
POO en C++: Héritage Multiple 474 © 1997-2003 Fabio HERNANDEZ
- 28. 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
POO en C++: Héritage Multiple 475 © 1997-2003 Fabio HERNANDEZ
- 29. Contrôle d'Avancement
Motivation
Exemple
Héritage et Ambiguïté
Héritage Répété
Résumé
POO en C++: Héritage Multiple 476 © 1997-2003 Fabio HERNANDEZ
- 30. Résumé
Contrairement à d'autres langages OO, en C++ une classe peut
hériter directement de plusieurs classe de base
L'héritage peut provoquer des ambiguïtés qui doivent être
levées par le programmeur
L'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é
POO en C++: Héritage Multiple 477 © 1997-2003 Fabio HERNANDEZ