Vous êtes sur la page 1sur 54

Programmation Orientée Objets

R. Ben Abbou & A. Zahi


FSTF, Fez, Maroc
dinzahi@yahoo.fr
Programmation Orientée Objets

Chapitre 4
Héritage
Plan
 Notion d’Héritage
 Classe dérivée
 Héritage simple
 Droits d’accès aux membres de la classe
 Redéfinition de fonctions membres
 Constructeurs, destructeurs
 Amitié

 Héritage multiple
 Syntaxe
 Conflits
 Héritage virtuel

 Fonctions virtuelles et classes abstraites

2011-2012 LST INFO, FSTF 3


Notion d’Héritage
 Permet de définir une classe (classe dérivée) à partir d’une ou plusieurs classes
existantes (classes de base) en l’enrichissant par de nouveaux attributs et de
nouvelles méthodes

 Représente la relation EST UN(E)


 Un chien est un animal
 Un voiture est un véhicule
 Une fourgonnette est une voiture

 Peut être
 Simple : Une seule classe de base
 Multiple: Plusieurs classes de base

2011-2012 LST INFO, FSTF 4


Notion d’Héritage
 Le concept d’héritage permet de:
 Expliciter les relations structurelles et sémantiques entre
les classes

 Réduire les redondances de description et de stockage des


propriétés

 Réutiliser les classes existantes

2011-2012 LST INFO, FSTF 5


Notion d’Héritage
Exemple

véhicule

avion voiture moto

de course fourgonnette

2011-2012 LST INFO, FSTF 6


Classe dérivée
 Modélise un cas particulier de la classe de base
 Si une classe D dérive de la classe B, alors
 D va hériter implicitement de l’ensemble:
 Des attributs de B
 De toutes les méthodes de B

 D peut définir des attributs et des méthodes supplémentaires


(enrichissement)

 D Peut redéfinir (masquer) certaines méthodes

2011-2012 LST INFO, FSTF 7


Héritage simple
 Syntaxe
class class_derivee:public class_de_base
{ /* définitions des méthodes et des attributs
spécifiques à la classe dérivée*/ … }

 Exemple
class personne {
char nom[20];
char prenom[20];
int CIN;
public:
void saisir(char*,char*,int);
void afficher();
};
class etudiant : public personne {
int CNE;
public:
void saisir_cne(int);
void afficher_cne();
};
2011-2012 LST INFO, FSTF 8
Héritage simple
Droit d’accès aux membres de classe
 Le droit d’accès aux membres d’une classe
peut être
 Accordé au « grand public »
 A partir de n’importe quel point du programme
 Concerne l’Interface publique d’une classe

 Restreint aux fonctions membres et aux fonctions


amies
 Reflète le principe d’encapsulation
 Concerne les membres protégés de la classe

2011-2012 LST INFO, FSTF 9


Héritage simple
Droit d’accès aux membres de classe
 Trois modes d’accès aux membres d’une
classe:
 public: Accès permis à toute fonction à partir de
n’importe quel point du programme
 private (mode par défaut) : Accès permis aux
fonctions membres de la classe et aux fonctions
amies
 protected (sémantique liée à l’héritage): Accès
permis aux fonctions membres de la classe, ceux
des classes dérivées et aux fonctions amies

2011-2012 LST INFO, FSTF 10


Héritage simple
Droit d’accès aux membres de classe
 Exemple
class A { void B::f(int x)
public: {
int pub; pub = x // ok accès possible
pro = x; // ok accès possible
protected : priv = x; //erreur
int pro; //accès interdit
}
private :
int priv; void fexterne(A oa, int x)
}; {
oa.pro= x; // erreur
class B : public A { oa.priv= x; // erreur
public: oa.pub = x; // ok
void f(int x); }
};

2011-2012 LST INFO, FSTF 11


Héritage simple
Droit d’accès aux membres de classe

 Mode de dérivation
 Syntaxe de définition

class class_derivee : mode class_de_base


{

}
 mode : désigne le mode de protection des membres des
classes

 Trois mode de dérivation :


– public
– private (mode par défaut)
– protected
2011-2012 LST INFO, FSTF 12
Héritage simple
Droit d’accès aux membres de classe

 Mode de dérivation public


Droits d’accès aux membres Droits d’accès aux membres
dans la classe de base dans la classe dérivée

public public

protected protected

private inaccessible

2011-2012 LST INFO, FSTF 13


Héritage simple
Droit d’accès aux membres de classe
 Mode de dérivation public: Exemple
class A { void B::f(int x)
public: {
int pub; pub =x; //accès possible (public)
pro =x;//accès possible (protected)
protected : priv =x;//accès interdit (private)
int pro; }

private : void fextern(B& b, int x)


int priv; {
};
b.pub = x; //accès possible (public)
class B : public A { b.pro = x;//accès interdit(protected)
public: b.priv = x;//accès interdit (private)
void f(int x); }
};

2011-2012 LST INFO, FSTF 14


Héritage simple
Droit d’accès aux membres de classe

 Mode de dérivation protected


Droits d’accès aux droits d’accès aux
membres dans la membres dans la
classe de base classe dérivée

public protected

protected protected

private inaccessible

2011-2012 LST INFO, FSTF 15


Héritage simple
Droit d’accès aux membres de classe
 Mode de dérivation protected: Exemple
class A { void B::f(int x)
public: {
int pub; pub =x;//ok accès possible
(protected)
protected : pro =x;//ok accès possible
(protected)
int pro;
priv =x;//accès interdit (private)
}
private :
int priv;
void fextern(B& b, int x)
};
{
b.pub = x; //accès interdit protected
class B : protected A {
b.pro = x;//accès interdit(protected)
public:
b.priv = x;//accès interdit (private)
void f(int x);
}
};

2011-2012 LST INFO, FSTF 16


Héritage simple
Droit d’accès aux membres de classe

 Mode de dérivation private


Droits d’accès aux droits d’accès aux
membres dans la membres dans la
classe de base classe dérivée

public private

protected private

private inaccessible

2011-2012 LST INFO, FSTF 17


Héritage simple
Droit d’accès aux membres de classe
 Mode de dérivation private: Exemple
class A { void B::f(int x)
public: {
int pub; pub =x;//ok accès possible (private)
pro =x;//ok accès possible (private)
protected : priv =x;//accès interdit (private)
int pro; }

private : void fextern(B& b, int x)


int priv; {
}; b.pub = x; //accès interdit (private)
b.pro = x;//accès interdit(private)
class B : private A { b.priv = x;//accès interdit (private)
public: }
void f(int x);
};

2011-2012 LST INFO, FSTF 18


Héritage simple
Affectation Classe de base/derivée
 Un objet d’une classe dérivée peut être affecté à un
objet de la classe de base
 Un objet d’une classe dérivée est un cas particulier de la
classe de base
 Un étudiant est « toujours une personne »

 Un objet d’une classe de base ne peut pas être


affecté à un objet de l’une des classes dérivées
 Un objet de la classe de base n’est pas forcément cohérent
avec la classe dérivée
 Une personne n’est pas forcément étudiant

 Exemple

2011-2012 LST INFO, FSTF 19


Héritage simple
Redéfinition de fonctions
 Besoin d’adapter certaines fonctions de la classe de base à la
classe dérivée

 La nouvelle fonction doit garder le même nom que celui de la


classe de base

 Redéfinition  surdéfinition

 La nouvelle définition (celle de la classe dérivée) va masquer


l’ancienne (celle de la classe de base)

2011-2012 LST INFO, FSTF 20


Héritage simple
Redéfinition de fonctions
 Exemple
class Rectangle { float Rectangle3D::surface()
protected: {
float largeur; return (2*largeur*hauteur+
float hauteur; 2*largeur*profondeur +
public: 2*hauteur*profondeur);
float surface(); }
};
float Rectangle::surface() void main()
{ {
return largeur*hauteur; Rectangle3D r;
} r.surface();//celle de la
classe Rectangle3D
}
class Rectangle3D :public Rectangle{
protected:
float profondeur;
public:
float surface();
};
2011-2012 LST INFO, FSTF 21
Héritage simple
Accès à une méthode cachée
 Parfois il est souhaitable d’accéder aux fonctions de la classe de base
qui sont cachées lors de la redéfinition

 Pour y accéder on utilise l’opérateur (::)


 Syntaxe
//définition de la méthode dans la classe de base
class_base::methode()
// redéfinition de la méthode dans la classe dérivée
class_derivee::methode()
// accès à la fonction de la classe de base
{
class_base::methode();
}
2011-2012 LST INFO, FSTF 22
Héritage simple
Accès à une méthode cachée
 Exemple
class Rectangle3D :public Rectangle{
protected:
float profondeur;
public:
float surface();
};
float Rectangle3D::surface()
{ if (profondeur == 0)
return Rectangle::surface();
else
return (2*largeur*hauteur+ 2*largeur*profondeur +
2*hauteur*profondeur);
}
2011-2012 LST INFO, FSTF 23
Héritage simple
Accès à une donnée cachée
 Utilisation non fréquente
 Exemple
class A {
protected: int a;
public: A(){a=0;}
};

class B : public A {
int a;
public: B(){ a=10;};
void f(){
cout << "A::" << A::a;//affiche 0
cout << "B::" << a; // affiche 10
}
};
2011-2012 LST INFO, FSTF 24
Héritage simple
Constructeur/destructeur

 Ordre d’appel
 Lors de la déclaration d’un objet de la classe dérivée, le
constructeur de la classe de base est appelé avant celui
de la classe dérivée

 De façon symétrique le destructeur de la classe de base


est appelée après le destructeur de la classe dérivée

 Si aucun constructeur n’est défini dans les classes de


base ou dérivées un constructeur par défaut est appelé

 Exemple
2011-2012 LST INFO, FSTF 25
Héritage simple
Constructeur de la classe de base

 Trois cas possibles pour le constructeur de


la classe de base

 Constructeur par défaut


 Constructeur n’est pas défini

 Constructeur sans paramètres


 Initialisation des membres données par des valeurs
aléatoires ou constantes

 Constructeur avec paramètres


2011-2012 LST INFO, FSTF 26
Héritage simple
Constructeur de la classe de base

 Dans les deux premiers cas, le constructeur


de la classe de base peut être invoqué
implicitement sans problème

 Dans le troisième cas le constructeur de la


classe de base requière des paramètres !!

2011-2012 LST INFO, FSTF 27


Héritage simple
Constructeur de la classe de base
Constructeur de la classe de
base avec paramètres

■ Comment lui passer les paramètres ?


■ Trois cas pour Le constructeur de la classe
dérivée
► Non défini
► Sans paramètres
► Avec paramètres

2011-2012 LST INFO, FSTF 28


Héritage simple
Constructeur de la classe de base avec paramètres
 Comment passer les paramètres au constructeur de la
classe de base?
 Constructeur de la classe dérivée n’est pas défini
 Erreur sauf si les arguments du constructeur de la classe
de base sont déclarés par défaut

 Constructeur de la classe dérivée sans paramètres


 Erreur sauf
– si les arguments du constructeur de la classe de base sont
déclarés par défaut
– Ou bien improviser des valeurs pour les passer au constructeur
de la classe de base
 Constructeur de la classe dérivée avec paramètres
 Un sous ensemble des paramètres est passé au
constructeur de la classe de base
2011-2012 LST INFO, FSTF 29
Héritage simple
Constructeur de la classe de base avec paramètres
 Comment passer les paramètres au
constructeur de la classe de base?
 Explicitement: lors de la déclaration du constructeur
de la classe dérivée

 Syntaxe
class_derivee::class_derivee(param1,par
am2,…): base(parami,…)
{ … }

 Exemple
2011-2012 LST INFO, FSTF 30
Héritage simple
Constructeurs : récapitulatif
Classe de base
Constructeur Constructeur sans Constructeur
par défaut paramètres avec paramètres
Appel implicite du Appel implicite du
Constructeur par constructeur par constructeur de la Erreur
défaut défaut classe de base Exemple
Classe dérivée

Exemple
Constructeur sans Appel implicite du Appel explicite du
paramètres constructeur par constructeur de la Erreur (sauf valeurs
défaut classe de base par défaut ou
Exemple improvisées)
Exemple
Constructeur avec Appel implicite du Appel implicite du Transmission des
paramètres constructeur par constructeur de la paramètres au
défaut classe de base constructeur de la
Exemple classe de base
Exemple
2011-2012 LST INFO, FSTF 31
Héritage simple
Constructeur de recopie

 Recopie des attributs de la classe de base et


ceux de la classe dérivée

 Deux cas :
 La classe dérivée n’a pas de constructeur de
recopie

 La classe dérivée possède un constructeur de


recopie
2011-2012 LST INFO, FSTF 32
Héritage simple
Constructeur de recopie
 Classe dérivée n’a pas de constructeur de
recopie
 Appel des constructeurs de recopie dans l’ordre
suivant:
 Constructeur de recopie explicite ou par défaut de la classe
de base

 Constructeur de recopie par défaut de la classe dérivée

 Exemple

2011-2012 LST INFO, FSTF 33


Héritage simple
Constructeur de recopie
 Classe dérivée possède un constructeur de recopie

 Pas d’appel automatique du constructeur de recopie de


la classe de base

 La classe dérivée
 Doit prendre en charge l’intégralité de la recopie de l’objet et
non seulement sa partie héritée

 Utilise le mécanisme de transmission entre constructeurs

 Exemple

2011-2012 LST INFO, FSTF 34


Héritage simple
Opérateur d’affectation
 L’opérateur ‘=‘ n’est pas défini dans la classe
dérivée
 Affectation membre à membre

 Appel implicite de l’opérateur par défaut ou


surdéfini de la classe de base pour copier la partie
héritée

 Appel ensuite de l’opérateur de la classe dérivée

 Exemple
2011-2012 LST INFO, FSTF 35
Héritage simple
Opérateur d’affectation
 L’opérateur ‘=‘ est surdéfini dans la classe
dérivée

 Appel de l’opérateur de la classe dérivée surdéfini

 Pas d’appel de l’opérateur de la classe de base


même s’il est surdéfini

 L’opérateur de la classe dérivée doit prendre en


charge l’affectation de tous l’objet

 Exemple

2011-2012 LST INFO, FSTF 36


Héritage simple
Amitié
 La déclaration d’amitié pour une classe
accorde aux fonctions de cette classe les
mêmes droits d’accès que ceux des fonctions
membres

 La déclaration d’amitié pour une classe ne se


propage pas aux classes dérivées

 L’amitié pour une fonction n’est pas héritée. A


chaque dérivation il faut définir l’amitié pour
cette fonction
2011-2012 LST INFO, FSTF 37
Héritage multiple
 Possibilité de créer des classes dérivées à partir
de plusieurs classes de base

 Pour chaque classe de base il y a la possibilité de


définir le mode de dérivation

 Il n’y a pas de restriction sur le nombre de


classes de base

 L’ordre des classes de base est pris en compte


lors de l’invocation des constructeurs et
destructeurs
2011-2012 LST INFO, FSTF 38
Héritage multiple
 Syntaxe

class D : mode_B1 B1,


mode_B2 B2,

mode_Bn Bn {
….
}

Mode ={public, protected, private}

2011-2012 LST INFO, FSTF 39


Héritage Multiple
Exemple

Point Complexe

Point_complexe

2011-2012 LST INFO, FSTF 40


Héritage Multiple
Exemple -Classe point-
class point {
int x,y;
public:
void initialise(int,int);
void deplace(int,int);
void affiche_point();
};
void point::initialise(int abs,int ord)
{
x=abs;
y=ord;
}
void point::deplace(int dx,int dy)
{
x+=dx;
y+=dy;
}
void point::affiche_point()
{
cout << "position :" <<x <<"," <<y <<"\n";
}

2011-2012 LST INFO, FSTF 41


Héritage Multiple
Exemple -Classe complexe
class complexe {
float reel,img;
public:
void saisir(int,int);
void affiche_complexe();
};
void complexe::saisir(int r,int i)
{
reel=r;
img=i;
}
void complexe::affiche_complexe()
{
cout << "abscisse :" <<x <<", ordonnee:" <<y <<"\n";
}

2011-2012 LST INFO, FSTF 42


Héritage Multiple
Exemple -Classe point_complexe-
class point_complexe : public point, public
complexe {
public:
void initialiser_pc(int ,int );
void affiche_pc();
};
void point_complexe::initialiser_pc(int n,int m)
{
initialise(n,m);
saisir(n,m);
}
void point_complexe::affiche_pc()
{
affiche_point();
affiche_complexe();
}

2011-2012 LST INFO, FSTF 43


Héritage multiple
 Les constructeurs sont appelés dans l’ordre
de déclaration des classes de base

 Les destructeurs sont appelés dans l’ordre


inverse de celui des constructeurs

 Exemple

2011-2012 LST INFO, FSTF 44


Héritage multiple
Conflits(1)

A B

 Problème: Les classes A et B possèdent des attributs ou des


fonctions portant le même nom

 Solution: Possibilité de les distinguer en utilisant l’opérateur de


résolution ::

 Exemple
2011-2012 LST INFO, FSTF 45
Héritage multiple
Conflits(2)

B C

D
 Problème: Duplication des membres fonctions ou attributs
dans tous les objets de D

 Solution : Dérivation virtuelle : le membre sera présent en un


seule exemplaire
2011-2012 LST INFO, FSTF 46
Héritage virtuel
 Possibilité de déclarer une classe « virtuelle » pour indiquer au
compilateur les classes à ne pas dupliquer

 Placement du mot clé virtuel devant le mode de dérivation de la


classe

 Syntaxe
class A {…}
// les descendants de B hériteront une seule fois
// les membres de A
class B : public virtual A {…}
class C : public virtual A {…}
class D : public B, public C {…}

 Exemple

2011-2012 LST INFO, FSTF 47


Héritage virtuel
Constructeurs
 Cas ou la classe A possède un constructeur avec
paramètres
 Pas de transmission d’arguments au constructeur de la
classe A dans les classes B et C qui sont virtuels

 Possibilité de transmettre les arguments nécessaires au


constructeur de la classe A

 Mais nécessité d’avoir un constructeur sans paramètres pour


la classe A

 Exemple

2011-2012 LST INFO, FSTF 48


Fonctions virtuelles
notion de typage
 La notion de typage concerne les objets dynamiques
et l’héritage
 Soient les instructions suivantes: A
A *pp; Afficher()
B b;
pp= &b;
 pp : pointeur de type A B
 pp : pointe sur un objet de type B
Afficher()

 L’instruction pp->Afficher(); correspond à quelle


afficher() de A ou de B?

 Question: comment choisir la fonction à exécuter?

2011-2012 LST INFO, FSTF 49


Fonctions virtuelles
notion de typage

 Typage statique:
 Le type de l’objet pointé est déterminé au moment
de la compilation

 Le choix de la fonction est déterminé par le type


du pointeur et non par celui de l’objet pointé

 L’instruction pp->Afficher(); correspond donc à


celle de la classe A

2011-2012 LST INFO, FSTF 50


Fonctions virtuelles
notion de typage
 Typage dynamique:
 Le type de l’objet pointé est déterminé lors de l’exécution
et non lors de la compilation

 Le choix des fonctions est donc fait lors de l’exécution

 Le choix de la fonction est déterminé par le type de l’objet


pointé
 L’instruction pp->Afficher(); correspondra à celle de la
classe B

 Obtenue par les fonctions virtuelles

2011-2012 LST INFO, FSTF 51


Fonctions virtuelles
 Ne pas confondre l’héritage virtuel et le statut
virtuel des fonctions membres

 Faire précéder la fonction en question par le


mot clé virtual

 Exemple

2011-2012 LST INFO, FSTF 52


Fonctions virtuelles pures
 Fonction déclarée
 Sans définition dans une classe

 Devant être redéfinie dans les classes dérivées

 Syntaxe
virtual type_retour nom_fonc(param)=0;

2011-2012 LST INFO, FSTF 53


Classes abstraites
 Classe destinée uniquement à la dérivation

 Pas de possibilité de définir une instance d’une classe


abstraite

 Toute classe comportant une fonction virtuelle pure


est abstraite

 Possibilité de définir des pointeurs et des références


sur une classe abstraite

 Exemple

2011-2012 LST INFO, FSTF 54

Vous aimerez peut-être aussi