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").

Héritage de classes

DéfinitionSyntaxe

1
class NomClasseDerive : <acces> NomClasseDeBase{  
2
//Definition de la classe 
3
};

AttentionEncapsulation

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

RemarqueConstructeurs

  • 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 :

1
#define PORTLED 3
2
class Led{
3
  private:
4
  int pinLed;
5
   public:
6
    Led (int);
7
    Led();
8
    void swon();
9
    void swoff();
10
};
11
Led::Led(int port){
12
    pinLed = port;
13
    pinMode(pinLed, OUTPUT);
14
}
15
Led::Led(){
16
    pinLed = PORTLED;
17
    pinMode(pinLed, OUTPUT);
18
}
19
void Led::swon(){
20
    digitalWrite(pinLed, HIGH);   // turn the LED on (HIGH is the voltage level)
21
    Serial.println("Allume !");
22
}
23
void Led::swoff(){
24
  digitalWrite(pinLed, LOW);    // turn the LED off by making the voltage LOW
25
  Serial.println("Eteint !");
26
}

La classe Cligno hérite de la classe Led :

1
class Cligno : public Led {
2
private:
3
  int delayCligno;
4
public:
5
  Cligno(int);
6
  void swonc();
7
  void swoffc();
8
 
9
};
10
Cligno::Cligno(int port) : Led(port){ //Le constructeur de la classe fille appelle le constructeur de la classe mère
11
  delayCligno = 1000;
12
}
13
void Cligno::swonc(){
14
  swon();
15
  delay(delayCligno);
16
}
17
void Cligno::swoffc(){
18
  swoff();
19
  delay(delayCligno);
20
}

AttentionConstructeurs 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 :

1
Cligno::Cligno(int port) : Led(port){ //Le constructeur de la classe fille appelle le constructeur de la classe mère
2
  delayCligno = 1000;
3
}

ComplémentAppel 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) :

1
class Cligno : public Led {
2
private:
3
  int delayCligno;
4
public:
5
  Cligno(int,int);
6
  void swonc();
7
  void swoffc();
8
 
9
};
10
Cligno::Cligno(int port,int delayC) : Led(port){
11
  delayCligno = delayC;
12
}
13
void Cligno::swonc(){
14
  
15
  swon();
16
  delay(delayCligno);
17
}
18
void Cligno::swoffc(){
19
  swoff();
20
  delay(delayCligno);
21
}

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