L'héritage
La syntaxe de l’héritage en C++ est semblable à celle de Java.
En C++, nous utilisons : public
au lieu de extends
pour indiquer l’héritage.
Si nous partons du principe qu’un pixel est un point avec de la
couleur, nous pouvons alors définir la classe Pixel
ainsi :
class Pixel : public Point {
public:
Pixel(int x, int y, uint16_t color);
void Paint();
private:
uint16_t color_;
};
En Java, on appelle le constructeur de la classe parente avec le mot clé super
.
En C++, on appelle simplement le constructeur de la classe parente directement avec son nom :
Pixel::Pixel(int x, int y, uint16_t color) : Point(x, y) {
color_ = color;
}
Dans l’exemple ci-dessus, l’appel du constructeur de la classe parente est à l’extérieur du body
et l’attribut color_
est initialisé à l’intérieur.
On peut aussi initialiser l’attribut à l’extérieur :
Pixel::Pixel(intx, inty, uint16_tcolor)
: Point(x, y)
, color_(color)
{}
Il n’est cependant pas possible d’appeler le constructeur de la classe parente à l’intérieur du body; l’appel doit être à l’extérieur,
Une autre caractéristique de C++ est que par défaut, les méthodes ne peuvent pas être
redéfinies dans une classe dérivée. C’est l’équivalent d’une méthode final
de Java.
Pour permettre une redéfinition d’une méthode, il faut préfixer la déclaration avec
le mot clé virtual
.
class Pixel : public Point {
public:
Pixel(int x, int y, uint16_t color);
virtual void Paint();
private:
uint16_t color_;
};
On peut maintenant définir un SuperPixel
qui hérite de Pixel
et qui
redéfinit Paint
:
class SuperPixel : public Pixel {
public:
SuperPixel(int x, int y, uint16_t color) : Pixel(x, y, color) {};
void Paint();
};
void SuperPixel::Paint() {
...
}
Pour bien montrer qu’une méthode est redéfinie, on peut ajouter le
mot clé override
après la déclaration :
class SuperPixel : public Pixel {
public:
SuperPixel(int x, int y, uint16_t color) : Pixel(x, y, color) {};
void Paint() override;
};
Comme en Java, les attributs privés ne sont pas accessibles dans les classes
dérivées. On peut les déclarer public, mais si on ne souhaite pas ouvrir
autant et n’autoriser l’accès qu’aux classes dérivées, on peut utiliser
le modificateur protected
.
class Point {
public:
Point();
Point(int x, int y);
void Move(int dx, int dy);
protected:
int x_;
int y_;
};
Le langage C++ est très complexe et cette courte introduction n’en a effleuré que la surface, mais ça devrait vous permettre de réaliser les TPs. Si vous souhaitez vous perfectionner en C++, vous trouverez beaucoup de références en lignes ainsi que de nombreux ouvrages spécialisés.
Note
Notez que le C++ supporte l’héritage multiple. C’est-à-dire qu’une classe
peut avoir plusieurs parents et contrairement à Java, il n’y a pas de
syntaxe spécifique pour une interface. Par contre, vous pouvez déclarer
une méthode abstraite (l’équivalent de abstract
en Java) en mettant
= 0
après la signature de la méthode. Par exemple :
virtual int f() = 0;
En plus des méthodes, le C++ permet aussi de redéfinir les opérateurs
tels que +
ou =
.
Ces concepts sont intéressants, mais leurs détails dépassent le cadre de ce chapitre.