View
1.685
Download
4
Category
Preview:
DESCRIPTION
Support material for a continued education course "Introduction to object oriented programming in C++". In French.
Citation preview
Fabio HernandezFabio.Hernandez@in2p3.fr
Programmation Orientée Objet en C++Programmation Orientée Objet en C++
13ème Partie: Héritage Multiple13ème Partie: Héritage Multiple
© 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
© 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é
© 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
© 1997-2003 Fabio HERNANDEZ452POO en C++: Héritage Multiple
Motivation (suite)Motivation (suite)
Figure
OpenFigure ClosedFigure
Polygon Ellipse
CircleTriangle Rectangle
Square
Segment Polyline
...
© 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
© 1997-2003 Fabio HERNANDEZ454POO en C++: Héritage Multiple
Motivation (suite)Motivation (suite)
Un polygone dessinable peut hériter de deux classes
PolygonDrawable
DrawablePolygon
© 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é
© 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);
© 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_;
};
© 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);...
© 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_;
};
© 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
© 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
© 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
© 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.
}
© 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
© 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é
© 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...
};
© 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...
};
© 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...
};
© 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()
© 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()
© 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();
}
© 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é
© 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
© 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
© 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
© 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é
© 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é
Recommended