Héritage de classes
L'héritage ou dérivation de classe, permet de créer une nouvelle classe à partir d'une classe existante.
La nouvelle classe, ou la classe dérivée, hérite les attributs (données membres) et les comportements (fonctions membres) de la classe dont elle dérive : cela signifie que les fonctions et les variables membres de la classe mère peuvent être disponibles (à condition qu'elles ne soient pas privées) dans la classe fille.
L'héritage permet de définir de nouveaux attributs et de nouvelles méthodes pour la classe dérivée, qui viennent s'ajouter à ceux et celles héritées.
Grâce à ce principe, il est possible de créer une hiérarchie de classes de plus en plus spécialisées.
Cela permet de ne pas avoir à repartir de zéro lorsque l'on veut spécialiser une classe existante.
L'héritage multiple, qui est le fait qu'une classe puisse hériter de plusieurs classes simultanément, n'est pas possible (avec Arduino).
Exemple :
Représentation de la relation de parenté entre les différentes classes sous forme de hiérarchie de classes, ou arborescence de classes
L'arborescence commence par une classe générale appelée parfois « superclasse » (ou encore classe de base, classe parent,...), ici « Animal »
Les classes dérivées (classe fille, sous-classe,...) deviennent de plus en plus spécialisées.
Ainsi, on peut généralement exprimer la relation qui lie une classe fille à sa mère par la phrase "est un" (ou en anglais "is a").

Définition : Syntaxe
class NomClasseDerive : <acces> NomClasseDeBase{
//Definition de la classe
};
Attention : Encapsulation
Lorsque, dans une classe mère, une variable (ou une fonction) est privée (private
), elle ne peut être utilisée par la classe fille. Si on souhaite que la variable ou la fonction soit à la fois privée pour le programmeur qui utilise la classe et publique pour la classe fille, il faut utiliser le mot clef protected
Remarque : Constructeurs
A chaque création d'objet, il est fait appel au constructeur de la classe correspondante. S'il s'agit d'une classe dérivée, le constructeur commence par appeler le constructeur par défaut de la classe de base et ainsi de suite si la classe de base dérive elle-même d'une autre classe. Cela a pour conséquence que les objets de base seront créés avant les objets dérivés.
Il n'est pas possible d'avoir une classe dérivée ne possédant qu'un constructeur par défaut alors que la classe de base ne possède qu'un constructeur avec paramètre. Il faut donc définir dans la classe dérivée un constructeur avec paramètres faisant appel au constructeur de la classe de base.
Exemple :
Soit la classe Led
suivante :
class Led{
private:
int pinLed;
public:
Led (int);
Led();
void swon();
void swoff();
};
Led::Led(int port){
pinLed = port;
pinMode(pinLed, OUTPUT);
}
Led::Led(){
pinLed = PORTLED;
pinMode(pinLed, OUTPUT);
}
void Led::swon(){
digitalWrite(pinLed, HIGH); // turn the LED on (HIGH is the voltage level)
Serial.println("Allume !");
}
void Led::swoff(){
digitalWrite(pinLed, LOW); // turn the LED off by making the voltage LOW
Serial.println("Eteint !");
}
La classe Cligno
hérite de la classe Led
:
class Cligno : public Led {
private:
int delayCligno;
public:
Cligno(int);
void swonc();
void swoffc();
};
Cligno::Cligno(int port) : Led(port){ //Le constructeur de la classe fille appelle le constructeur de la classe mère
delayCligno = 1000;
}
void Cligno::swonc(){
swon();
delay(delayCligno);
}
void Cligno::swoffc(){
swoff();
delay(delayCligno);
}
Attention : Constructeurs avec paramètres
Lorsque la classe fille et la classe mère possèdent un constructeur avec paramètres, la classe fille doit spécifier explicitement l'appel du constructeur de la classe mère :
Cligno::Cligno(int port) : Led(port){ //Le constructeur de la classe fille appelle le constructeur de la classe mère
delayCligno = 1000;
}
Complément : Appel de fonctions de la classe mère
Dans la définition des fonctions membres de la classe fille, il est possible d'appeler des fonctions membres de la classe mère. Ainsi dans l'exemple, on trouve un appel à la fonction swon()
(définie dans la classe mère) dans la fonction membre swonc()
(définie dans la classe fille)
Exemple :
On a ici modifié légèrement la classe fille, en utilisant un constructeur à 2 paramètres (le numéro de port et la durée de temporisation) :
class Cligno : public Led {
private:
int delayCligno;
public:
Cligno(int,int);
void swonc();
void swoffc();
};
Cligno::Cligno(int port,int delayC) : Led(port){
delayCligno = delayC;
}
void Cligno::swonc(){
swon();
delay(delayCligno);
}
void Cligno::swoffc(){
swoff();
delay(delayCligno);
}
On fait donc explicitement appel au constructeur de la classe mère (ici Led(port)
) pour lui indiquer quel paramètre utiliser (puisque le constructeur de la classe fille en a deux)
Complément :
Autres exemples sur le site Locoduino