Programmer en C++
Les classes : Héritage

1. Introduction

Une classe peut hériter des fonctions et des variables membres d'une autre classe si ces fonctions ou variables sont déclarées publiques ou protégées. La classe qui hérite se nomme généralement la classe fille. La classe mère est celle qui cède l'héritage. La syntaxe est la suivante :

class classeMere
{
};


class classeFille : public classeMere
{
};

Imaginons un jeu dans lequel des navires peuvent se déplacer dans une grille repérée par un couple de point(x, y). La classe mère est représentée par la classe "Navire". La classe "SousMarin" hérite de la classe "Navire".
Voici ce que donnerait la déclaration de nos deux classes :

class Navire
{
private:
    string m_nom;
    int m_x;
    int m_y;
public:
    void initialiser(string, int, int);
    void afficher();
};


class SousMarin : public Navire
{
private:
    int m_profondeur;
public:
    void initSousMarin(string, int, int, int);
};

Ecrivons maintenant les définitions ;

// Definition des fonctions de la classe Navire
void Navire::initialiser(string nom, int x, int y)
{

    m_nom = nom;
    m_x = x;
    m_y = y;
}


void Navire::afficher()
{

    cout << "Je suis un " << m_nom << endl;
    cout << "et ma position est (" << m_x << ", " << m_y << ")" << endl;
}


// Definition des fonctions de la classe SousMarin
void SousMarin::initSousMarin(string nom, int x, int y, int profondeur)
{

    m_profondeur = profondeur;
    initialiser(nom, x, y);
}


void SousMarin::afficherSM()
{

    afficher();
    cout << " Je navigue a une profondeur de " << m_profondeur << " m" << endl;
}

Notez bien que la classe fille (ici SousMarin) n'a pas accès aux variables membres de la classe mère (ici Navire). On est donc forcé de passer par les fonctions membres de la classe "Navire", qui sont publiques, pour initialiser le nom et la position du sous marin.
Les fonctions initialiser() et afficher() qui sont des fonctions membres de la classe "Navire", se comporte comme si elles étaient des fonctions membres de la classe "SousMarin".
Peut être êtes vous choqué de l'écriture directe de initialiser() et afficher() dans les fonctions membres de la classe "SousMarin", sans qu'elle soit précédée de l'instance qui appelle ces fonctions ? En fait ce n'est pas nécessaire car les fonctions membres de la classe "SousMarin" transmettent de façon automatique ces informations.
Toutefois si vous désirez rendre les choses plus claires, vous avez la possibilité d'écrire :

this->initialiser(nom, x, y);
this->afficher();

Utilisons maintenant ces classes dans "main()" :

int main()
{

    Navire nav;
    nav.initialiser("cargo", 5, 6);
    nav.afficher();
    SousMarin sm;
    sm.initSousMarin("Uboat", 2, 2, 30);
    sm.afficherSM();
    return 0;
}

Voilà ce qu'on obtient en lançant le programme :

Je suis un cargo
et ma position est (5, 6)
Je suis un Uboat
et ma position est (2, 2)
Je navigue a une profondeur de 30 m

2. Classes possédant des noms de fonction membre communes

Une classe fille et une classe mère peuvent-elles posséder chacune une fonction de même nom ? La réponse est oui, mais dans ce cas il y a, comme le montre l'exemple suivant, un risque que la fonction s'appelle elle même.

void SousMarin::afficher()
{

    afficher();
    cout << " Je navigue a une profondeur de " << m_profondeur << " m" << endl;
}

Pour lever le doute sur le choix de la bonne fonction, nous utilisons l'opérateur de résolution de portée "::" associé au nom de la classe concernée.

void SousMarin::afficher()
{

    Navire::afficher();
    cout << " Je navigue a une profondeur de " << m_profondeur << " m" << endl;
}