30
Fabio Hernandez [email protected] Programmation Orientée Objet en C++ Programmation Orientée Objet en C++ 13ème Partie: Héritage Multiple 13ème Partie: Héritage Multiple

Partie 13: Héritage Multiple — Programmation orientée objet en C++

Embed Size (px)

DESCRIPTION

Support material for a continued education course "Introduction to object oriented programming in C++". In French.

Citation preview

Page 1: Partie 13: Héritage Multiple — Programmation orientée objet en C++

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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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++

© 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é