CH Patrons Heritage Polymorphisme

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 69

Chapitre

les patrons de fonctions et classes

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 1/1
Patrons de fonctions : Création d’un patron de fonctions

Comment on peut écrire une fonction min fournissant le minimum de deux


valeurs de même type reçues en arguments?
Définition de la fonction min pour le type int:
int min (int a, int b)
{
if (a < b) return a ; // ou return a < b ? a : b ;
else return b ;
}
Définition de la même fonction pour le type float
float min (float a, float b)
{
if (a < b) return a ; // ou return a < b ? a : b ;
else return b ;
}

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 2/1
Création d’un patron de fonctions

Besoin d’autres fonctions pour d’autres types.


Il s’agit d’écrire nombreuses fonctions!!
Solution: utilisation d’un seul patron de fonctions:

template <class T> T min (T a, T b)


{
if (a < b) return a ; // ou return a < b ? a : b ;
else return b ;
}

L’en-tête de la fonction est devenu:


template <class T> T min (T a, T b)
template <class T> precise que l’on a affaire a un patron (template) dans
lequel apparait un paramétré de type nommé T.
Le mot-clé class est utilisé pour préciser que T est un paramètre de type.
T min (T a, T b) précise que min est une fonction recevant deux arguments
de type T et fournissant un résultat du même type.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 3/1
Utilisations du patron de fonctions

// Création d’un patron de fonctions


template <class T > T min (T a, T b)
{ if (a < b) return a ; // ou return a < b ? a : b ;
else return b ;
}
// Exemple d’utilisation du patron de fonctions min
main()
{ int n=4, p=12 ;
float x=2.5, y=3.25 ;
cout << ”min(n, p) = ” << min(n, p) << ” \ n”;
cout << ”min(x, y ) = ” << min(x, y ) << ” \ n”;
}

min (n, p) = 4
min (x, y) = 2.5

Avec l’appel min (n, p), le compilateur fabriquera (instanciera) la fonction min (dite
fonction patron) correspondant à des arguments de type int.
Même chose pour min avec deux arguments de type float, le compilateur instanciera une
autre fonction patron min correspondant a des arguments de type float, et ainsi de suite.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 4/1
Utilisations du patron de fonctions

Le patron min peut être utilisé pour des arguments de n’importe quel type:
Type prédefini (short, char, double, int *, char *, int * *, etc.)
Type défini par l’utilisateur (notamment structure ou classe).
Si n et p sont de type int, un appel tel que min (&n, &p) conduit le
compilateur a instancier une fonction int * min (int *, int *).
Le code:

int n=4, p=12 ;


cout << ”&n = ” << &n << ” &p = ” << &p << ” \ n”;
cout << ”min(&n, &p) = ” << min(&n, &p) << ” \ n”;

Donne comme résultat

&n = 0xbfa08998 &p = 0xbfa0899c


min (&n, &p) = 0xbfa08998

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 5/1
Utilisations du patron de fonctions

Le code:

char * adr1 = ”monsieur”, * adr2 = ”bonjour” ;


cout << ”min(adr 1, adr 2) = ” << min(adr 1, adr 2);

Donne comme résultat

min (adr1, adr2) = monsieur

L’appel min(adr1,adr2) génère la fonction


char * min (char * a, char * b)
{
if (a < b) return a ;
else return b ;
}
La comparaison a<b porte sur les valeurs des pointeurs a et b.
L’operateur << (affichage) porte sur les chaines situées aux adresses a et b.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 6/1
Utilisations du patron de fonctions
Application au type class
Pour pouvoir appliquer le patron min à une classe, il faut que l’opérateur <
puisse s’appliquer à deux opérandes de ce type classe.
Il faut le surcharger!!
Considérons la classe vect

class vect {
int x, y ;
public :
vect (int abs=0, int ord=0) { x=abs ; y=ord; }
void affiche () { cout << x << ”” << y ; }
friend int operator < (vect, vect) ;
};
int operator < (vect a, vect b)
{
return a.x*a.x + a.y*a.y < b.x*b.x + b.y*b.y ;
}

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 7/1
Utilisations du patron de fonctions
Application au type class

Exemple d’utilisation :

main()
{
vect u (3, 2), v (4, 1), w ;
w = min (u, v) ;
cout << ”min(u, v ) = ”;
w.affiche() ;
}
Sortie :
min (u, v) = 3 2

Si nous cherchons a appliquer notre patron min a une classe pour laquelle
l’opérateur < n’est pas défini, le compilateur le signalera.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 8/1
Utilisation des paramètres de type dans la définition d’un
patron

Un patron de fonctions peut comporter un ou plusieurs paramètres de type.


Chaque paramètre de type doit être précédé du mot-clé class :
template <class T, class U> fct (T a, T * b, U c)
{
...
}
Les paramétres de type peuvent intervenir
Dans l’en-tete ;
template <class T, class U> fct (T a, T * b, U c)
Dans des déclarations de variables locales ;
T x ; // variable locale x de type T
Dans les instructions exécutables. // allocation tableau de 10 éléments de
type T
adr = new T [10] ;

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 9/1
Utilisation des paramètres de type dans la définition d’un
patron
Exemple d’utilisation de paramètres de type :

template <class T, class U> fct (T a, T * b, U c)


{
T x ; // variable locale x de type T
U * adr ; // variable locale adr de type U *
...
adr = new T [10] ; // allocation tableau de
// 10 elements de type T
...
n = sizeof (T) ;
...
}

Remarque: il est nécessaire que chaque paramètre de type apparaisse au


moins une fois dans l’en-tête du patron.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 10 / 1
Identification des paramètres de type d’une fonction patron
Lors d’un appel d’un patron, il doit y avoir une correspondance absolue des
types.
Exemple :
template <class T> T min (T a, T b)
{ if (a < b) return a ;
else return b ;
}
...
int n ; char c ; unsigned int q ;
const int ci1 = 10, ci2 = 12 ;
int t[10] ;
int * adi ;
...
min (n, c) // erreur
min (n, q) // erreur
min (n, ci1) // erreur : const int et int ne correspondent pas
min (ci1, ci2) // min (const int, const int)
min (t, adi) // min (int *, int *) car ici, t est converti
// en int *, avant appel
Said Charfi (Associate Professor Department of Computer Science,
Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 11 / 1
Identification des paramètres de type d’une fonction patron

Il est possible d’intervenir sur ce mécanisme d’identification de type.


Autoriser la non correspondance absolue entre les types!!
Exemple :
min<int> (c, n) /* force l’utilisation de min<int>, et donc la conversion de
c en int ; le résultat sera de type int */
min<char> (q, n) /* force l’utilisation de min<char>, et donc la conversion
de q et de n en char ; le résultat sera de type char */

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 12 / 1
Patrons de classes: Introduction

Comme les patrons de fonctions, C++ permet de définir des patrons de


classes (appelés aussi les classes génériques).
Ecriture d’une seule classe que le compilateur puisse adapter
automatiquement a différents types.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 13 / 1
Création d’un patron de classes

Création d’une classe point


Les coordonnées des points sont de type int.
class point {
int x ; int y ;
public :
point (int abs=0, int ord=0) ;
void affiche () ;
// .....
}
Les coordonnées des points sont de type float.
class point {
float x ; float y ;
public :
point (float abs=0, float ord=0) ;
void affiche () ;
// .....
};

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 14 / 1
Création d’un patron de classes

Définir une classe pour chaque type des coordonnées!!! Remplacer le mot int
dans la classe point par le type voulu.
Les choses peuvent être simplifiées en définissant un seul patron de classe :
template <class T> class point {
Tx;Ty;
public :
point (T abs=0, T ord=0) ;
void affiche () ;
};
Définition des fonctions membres de la classe, comment?
Il y a deux possibilités.
Fonction en ligne.
N’est pas fonction en ligne.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 15 / 1
Définition des fonctions membres

Une fonction en ligne: il suffit tout simplement d’utiliser le paramètre T a


bon escient.
point (T abs=0, T ord=0)
{
x = abs ; y = ord ;
}
Le patron de classes correspondant:
template <class T> class point
{
Tx;Ty;
public :
point (T abs=0, T ord=0)
{
x = abs ; y = ord ;
}
void affiche () ;
};

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 16 / 1
Définition des fonctions membres

fonction membre définie en dehors de la définition de classe:


Il faut rappeler au compilateur :
que dans la définition de cette fonction, vont apparaitre des paramétres de
type. Il faut utiliser de nouveau
template <class T>
le nom du patron concerné. Supposons que nous souhaitons définir la fonction
affiche. Son nom sera
point<T>::affiche ()
si on définit la fonction affiche en dehors de la classe, son en-tête sera comme
suit
template <class T> void point<T>::affiche ()

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 17 / 1
Définition des fonctions membres

Le patron point pourrait être défini comme suit:


#include < iostream >
using namespace std ;
// creation d’un patron de classe
template <class T> class point
{
Tx;Ty;
public :
// Definition en ligne
point (T abs=0, T ord=0)
{
x = abs ; y = ord ;
}
void affiche () ;
};
// definition de la fonction affiche
// en dehors de la classe
template <class T> void point<T>::affiche ()
{
cout << ”Coordonnees : ” << x
<< ”” << y << ” \ n”; }

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 18 / 1
Utilisation d’un patron de classes

Pour une déclaration telle que


point <int> ai ;
le compilateur instancie la définition d’une classe point pour T = int.
De même pour la déclaration
point <double> ad ;
instanciation de la définition la classe point pour T = double.
Déclaration en spécifiant les arguments a fournir au constructeur:
point <int> ai (3, 5) ;
point <double> ad (3.5, 2.3) ;

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 19 / 1
Exemple d’un patron de classes
Création et utilisation
#include < iostream >
using namespace std ; // creation d’un patron
de classe
template <class T> class point{
Tx;Ty;
public :
point (T abs=0, T ord=0) Sortie :
{ x = abs ; y = ord ; } coordonnees : 3 5
void affiche () } ; coordonnees : d y
template <class T>
void point<T>::affiche ()
coordonnees : 3.5 2.3
{ cout << ”Coordonnees : ” Le patron de classes point est doté d’un
<< x << ”” << y << ” \ n”;} constructeur en ligne et d’une fonction
main (){ membre (affiche) non en ligne.
point <int> ai (3, 5) ;
ai.affiche () ;
point <char> ac (d, y) ;
ac.affiche () ;
point <double> ad (3.5, 2.3) ;
ad.affiche () ;}

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 20 / 1
Les paramètres de type d’un patron
Les paramètres de type d’un patron de classes peuvent être en nombre
quelconque.
Ils sont utilisés dans la définition du patron de classes.
Patron de classes avec 3 paramètres de type
template <class T, class U, class V>
class essai {
Tx;
U t[5] ;
...
V fm1 (int, U) ;
};
Trois paramètres de type T, U, V
template <class T, class U, class V>
Un membre x de type T
Un tableau t de 5 éléments de type U
Déclaration d’une fonction membre recevant 2 arguments de type int et U et
renvoyant un résultat de type V
Said Charfi (Associate Professor Department of Computer Science,
Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 21 / 1
Instanciation d’une classe patron

Rappel : Une classe patron est une instance particulière d’un patron de
classes.
Une classe patron se déclare en fournissant a la suite du nom de patron un
nombre d’arguments effectifs (noms de types) égal au nombre de paramètres
figurant dans la liste du patron.
essai <int, float, int> ce1 ;
essai <int, int *, double > ce2 ;
essai <char *, int, obj> ce3 ;
Dans la dernière déclaration (instanciation de la classe patron), on suppose
que obj est un type préalablement défini.
Possible d’utiliser comme paramètre de type effectif un type instancie a l’aide
d’un patron de classes.
essai <float, int<int>, double> ce4 ;
essai <point<int>, point<float>, char *> ce5;

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 22 / 1
Chapitre

L’héritage

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 23 / 1
Objectifs du chapitre

Ce chapitre a pour but :


de présenter en détail la notion fondamentale d’héritage
de vous présenter encore quelques subtilités au sujet des constructeurs et des
destructeurs

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 24 / 1
Héritage
Après les notions d’encapsulation et d’abstraction, le troisième aspect
essentiel des objets est la notion d’héritage
L’héritage est une technique extrêmement efficace pour créer des classes plus
spécialisées, appelées sous-classes, à partir de classes plus générales déjà
existantes, appelées super-classes.
Elle représente la relation << est − un >>

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 25 / 1
Hiérarchie de classes
un exemple

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 26 / 1
Héritage

plus précisément, lorsqu’une sous-classe C1 est créée à partir d’une classe C,


C1 va hériter de (i.e. recevoir) l’ensemble :
des attributs de C
des méthodes de C (sauf les constructeurs/destructeurs)
les attributs et méthodes de C vont être disponibles pour C1 sans que l’on ait
besoin de les redéfinir explicitement dans C1.
De plus :
des attributs et/ou méthodes supplémentaires peuvent être définis par la
sous-classe C1
ces membres constituent l’enrichissement apporté par cette sous-classe.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 27 / 1
Héritage

L’héritage permet donc :


d’expliciter des relations structurelles et sémantiques entre classes
de réduire les redondances de description et de stockage des propriétés

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 28 / 1
Héritage
Supposons par exemple que l’on veuille étendre la classe Point précédemment
définie en lui ajoutant le nouvel attribut couleur.
Une façon de procéder est de créer une nouvelle classe, par exemple Pixel, définie
comme une sous-classe de Point et contenant le nouvel attribut couleur.
on évite ainsi de dupliquer inutilement du code commun aux classes Point et Pixel.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 29 / 1
Héritage

par transitivité, les instances d’une sous-classe possèdent : les attributs et


méthodes de l’ensemble des classes parentes (classe parente, classe parente
de la parente, etc . . .)
la notion enrichissement par héritage :
crée un réseau de dépendances entre classes,
ce réseau est organisé en une structure arborescente où chacun des nœuds
hérite des propriétés de l’ensemble des nœuds du chemin remontant jusqu’à la
racine.
ce réseau de dépendance définit une hiérarchie de classes

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 30 / 1
La pratique en C++

Définition d’une sous-classe en C++ :


Syntaxe :
class NomClasseEnfant : public NomClasseParente
{
/* Déclaration des attributs et méthodes
spécifiques à la sous-classe */
//...
};
Exemple :
class Pixel : public Point
{
Couleur couleur;
//...
};

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 31 / 1
Accès aux membres d’une sous-classe

Jusqu’à maintenant, l’accès aux membres (attributs et méthodes) d’une classe


pouvait être :
soit public : visibilité totale à l’intérieur et à l’extérieur de la classe (mot-clé
public).
soit privé : visibilité uniquement à l’intérieur de la classe (mot-clé private ou
par défaut).
Un troisième type d’accès régit l’accès aux attributs/méthodes au sein d’une
hiérarchie de classes :
l’accès protégé : assure la visibilité des membres d’une classe dans les classes
de sa descendance. Le mot clé est << protected >>.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 32 / 1
Définition des niveaux d’accès

L’ordre de définition conseillé est le suivant :


class NomClasse[: public NomClasseParente]
{
// par défaut : privé
public:
// attributs et méthodes publics
protected:
// attributs et méthodes protégés
private:
// attributs et méthodes privés
};
Mais il peut y avoir plusieurs zones publiques, protégées ou privées dans une
même définition de classe.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 33 / 1
Accès protégé (1)
Le niveau d’accès protégé correspond à une extension du niveau privé aux membre
des sous-classes
Exemple :
class Rectangle
{
public:
Rectangle(): largeur(1.0), hauteur(2.0) {}
protected:
double largeur; double hauteur;
};
class RectangleColore : public Rectangle
{
public:
...
void carre() { largeur = hauteur; }
protected:
Couleur couleur;
};
Said Charfi (Associate Professor Department of Computer Science,
Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 34 / 1
Accès protégé (2)
Le niveau d’accès protégé correspond à une extension du niveau privé aux membre
des sous-classes... mais uniquement dans ce rôle (de sous-classe) pas dans le rôle
de classe extérieure :
Exemple :
class A {
...
protected: int a;
private: int prive;
};
class B: public A {
public:
...
void f(B autreB, A autreA, int x) {
a = x; // OK A::a est protected => accès possible
// prive = x; // erreur : A::prive est private
// a += autreB.prive; // erreur (même raison)
a += autreB.a; // OK : dans la même classe (B)
}
};
Said Charfi (Associate Professor Department of Computer Science,
Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 35 / 1
Restriction des accès lors de l’héritage

Les niveaux d’accès peuvent être modifiés lors de l’héritage


Syntaxe :
class ClasseEnfant: [acces] classeParente
{
/* Déclaration des membres
spécifiques à la sous-classe */
//...
};
où accès est le mot-clé public, protected ou private. Par défaut, l’accès est privé.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 36 / 1
Restriction des accès lors de l’héritage(2)

Récapitulatif des changements de niveaux d’accès aux membres hérités, en


fonction du niveau initial et du type d’héritage :
Accès initial
public protected private
public public protected Pas d’accès
Héritage protected protected protected Pas d’accès
private private private Pas d’accès
Le type d’héritage constitue une limite supérieure à la visibilité.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 37 / 1
Utilisation des droits d’accès

Membres publics : accessibles pour les utilisateurs de la classe


Membres protégés : accessibles aux autres programmeurs pour d’éventuelles
extensions par héritage de la classe
Membres privés : utilisable par les fonctions membres et les classes et
opérations amies de cette seule classe, à l’exception des sous-classes;

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 38 / 1
Masquage dans une hiérarchie

Masquage : un identificateur qui en cache un autre


Situation possible dans une hiérarchie :
Même nom d’attribut/méthode utilisé sur plusieurs niveaux
Peu courant pour les attributs
Très courant et pratique pour les méthodes
Exemple :
Rectangle3D hérite de Rectangle
calcul de la surface pour les Rectangle3D
2* (largeur*hauteur) + 2*(largeur*profondeur)+ 2*(hauteur*profondeur)
calcul de la surface pour tous les autres Rectangle :
(largeur*hauteur)
Faut-il re-concevoir toute la hiérarchie ?
Non, on ajoute simplement une méthode surface spéciale à Rectangle3D

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 39 / 1
Masquage dans une hiérarchie (2)
La méthode surface de Rectangle3D cache celle de Rectangle
Un objet de type Rectangle3D n’utilisera donc jamais la méthode surface de
la classe Rectangle
Vocabulaire OO :
Méthode héritée = méthode générale, méthode par défaut
Méthode qui cache la méthode héritée = méthode spécialisée

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 40 / 1
Masquage dans une hiérarchie (3)

Code C++ de l’exemple :


class Rectangle{
public:
// les constructeurs seraient ici...
double surface() {return (largeur*hauteur);}
protected:
double largeur; double hauteur;
// le reste de la classe...
};
class Rectangle3D : public Rectangle{
public:
// les constructeurs seraient ici...
double surface(){
return(2.0*(largeur*hauteur) + 2.0*(largeur*profondeur)
+ 2.0*(hauteur*profondeur));
}
protected:
double profondeur;
// le reste de la classe...
};

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 41 / 1
Accès à une méthode masquée

Il est parfois souhaitable d’accéder à une méthode/un attribut caché(e)


Exemple :
Surface des Rectangle3D ayant une profondeur nulle (largeur*hauteur)
surface identique au calcul de surface pour les Rectangle
Code désiré :
1 Objet non-Rectangle3D :
Méthode générale (surface de Rectangle)
2 Objet Rectangle3D :
Méthode spécialisée (surface de Rectangle3D)
3 Objet Rectangle3D de profondeur nulle :
D’abord la méthode spécialisée
Ensuite appel à la méthode générale depuis la méthode spécialisée

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 42 / 1
Accès à une méthode masquée (2)

Pour accéder aux attributs/méthodes caché(e)s de la super-classe : on utilise


l’opérateur de résolution de portée
Syntaxe : NomClasse::methode ou attribut
Exemple : Rectangle::surface()
class Rectangle3D : public Rectangle{
//... constructeurs, attributs comme avant
double surface () {
if (profondeur == 0.0)
return Rectangle::surface();
else
return(2.0*(largeur*hauteur) + 2.0*(largeur*profondeur)
+ 2.0*(hauteur*profondeur));
}
};

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 43 / 1
Constructeurs et destructeurs

La construction d’un objet d’une classe dérivée comporte:


la réservation de la place pour l’objet;
l’appel d’un constructeur approprié (constructeur par défaut) de la classe de
base;
appel des constructeurs pour les membres objets;
l’exécution du corps de la fonction constructeur.
Un constructeur autre que celui par défaut est indiqué dans la liste d’initialisation.
La destruction d’un objet d’une classe dérivée:
appel du destructeur de la classe dérivée;
appel du destructeur de la classe de base.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 44 / 1
Constructeurs et héritage

Lors de l’instanciation d’une sous-classe, il faut initialiser :


les attributs propres à la sous-classe
les attributs hérités des super-classes
MAIS...
...il ne doit pas être à la charge du concepteur des sous-classes de réaliser
lui-même l’initialisation des attributs hérités
L’accès à ces attributs peut notamment être interdit !
L’initialisation des attributs hérités doit donc se faire au niveau des classes où ils
sont explicitement définis.
Solution : l’initialisation des attributs hérités doit se faire en invoquant les
constructeurs des super-classes.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 45 / 1
Constructeurs et héritage (2)

L’invocation du constructeur de la super-classe se fait au début de la section


d’appel au constructeurs des attributs. Syntaxe :
SousClasse(liste de paramètres):
SuperClasse(Arguments),attribut1(valeur1)...attributN(valeurN)
{
// corps du constructeur
}
Lorsque la super-classe admet un constructeur par défaut, l’invocation
explicite de ce constructeur dans la sous-classe n’est pas obligatoire
Le compilateur se charge de réaliser l’invocation du constructeur

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 46 / 1
Constructeurs et héritage (3)

Exemple :
class point{
int x,y;
public : point(int abs=0, int ord =0){
x=abs; y=ord;
}
∼point(){}
};
class pixel : public point {
short couleur;
public :
pixel(int abs=0,int ord=0,short cl=1):point(abs,ord),
couleur(cl){
}
∼pixel(){
}
};

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 47 / 1
Constructeurs et héritage (4)
Si la classe parente n’admet pas de constructeur par défaut, l’invocation
explicite d’un de ses constructeurs est obligatoire dans les constructeurs de la
sous-classe
La sur-classe doit admettre au moins un constructeur explicite.
Exemple :
class Rectangle {
protected: double largeur; double hauteur;
public:
Rectangle(double l, double h) : largeur(l), hauteur(h)
{}
// le reste de la classe...
};
class Rectangle3D : public Rectangle {
protected: double profondeur;
public:
Rectangle3D(double l, double h, double p)
: Rectangle(l,h), profondeur(p){}
// le reste de la classe...
};
Said Charfi (Associate Professor Department of Computer Science,
Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 48 / 1
Constructeurs et héritage (5)
Autre exemple (qui ne fait pas la même chose) :
class Rectangle{
protected: double largeur; double hauteur;
public:
Rectangle() : largeur(0.0), hauteur(0.0)
{}
// le reste de la classe...
};
class Rectangle3D : public Rectangle {
protected: double profondeur;
public:
Rectangle3D(double p)
: profondeur(p)
{}
// le reste de la classe...
};
Ici il n’est pas nécessaire d’invoquer explicitement le constructeur de la classe
parente puisque celle-ci admet un constructeur par défaut.
Said Charfi (Associate Professor Department of Computer Science,
Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 49 / 1
Héritage multiple
Une classe peut hériter de plusieurs classes. Les classes de bases sont alors
énumérées dans la définition.
class D : public B1, public B2 {...}
Exemple:
class point{
int x,y;
public:
point(...){...}
∼point(){...}
void afficher(){...}
};
class coul {
short couleur;
public :
coul(...){...}
∼coul(...){...}
void afficher(){...}
};
// classe dérivée
class pixel : public point, public coul {...
pixel(...):point(...),coul(...){
...}
void afficher(){...} };
Said Charfi (Associate Professor Department of Computer Science,
Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 50 / 1
Héritage multiple : Héritage en Diamant

La difficulté de ce type d’héritage


commence quand deux classes parentes
héritent d’une même classe. On se
retrouve alors dans la situation suivante :
C hérite de A
B hérite de A
D hérite de B et de C
B et C vont donc construire chacun une
classe A. Il y a donc un risque de conflit
quand, dans D, on veut accéder à une
donnée de A.
Solution : Les Classes Virtuelles!!

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 51 / 1
Chapitre

Le polymorhpisme

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 52 / 1
Qu’est ce que le polymorphisme

L’édition de lien est l’opération qui associe, à l’appel d’une fonction, l’adresse du
code de la fonction.
On distingue
La liaison statique (ou précoce): effectuée à la compilation
La liaison dynamique (ou tardive) : effectuée à l’exécution.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 53 / 1
Qu’est ce que le polymorphisme (2)

Le polymorphisme est la capacité, pour une fonction, d’être interprétée


différemment en fonction de l’objet auquel elle s’applique.
On distingue:
Le polymorphisme statique : c’est la surcharge. Le sens de la fonction est
déterminé statiquement par la signature des arguments à l’appel.
Le polymorphisme dynamique : c’est le véritable polymorphisme. Le sens de
la fonction est déterminé par le type effectif de l’objet à l’appel.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 54 / 1
Qu’est ce que le polymorphisme (3)

Le polymorphisme ne s’applique qu’aux méthodes d’une classe.


Avantages:
encourage l’abstraction,
facilite l’extensibilité.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 55 / 1
Héritage (rappel)

Dans une hiérarchie de classes, la sous-classe hérite de la super-classe :


tous les attributs/méthodes (sauf constructeurs et destructeur)
le type
L’héritage est transitif.
Héritage du type : on peut affecter un objet de type sousclasse à une variable de
type super-classe.
Exemple:
Shape fig1;
Rectangle fig2;
fig1 = fig2;

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 56 / 1
Exemple
class Base
{
public: void show(){cout << ”Base \ n”;}
};
class Derv1 : public Base // derived class 1
{
public: void show(){cout << ”Derv 1 \ n”;}
};
class Derv2 : public Base // derived class 2 Résultat d’exécution:
{
Les instances de Derv1 et
public: void show(){cout << ”Derv 2 \ n”;}
}; Derv2 sont substituables
int main() aux instances de Base :
{ Compatibilité
Derv1 dv1; // object of derived class 1
Derv2 dv2; // object of derived class 2
ascendante des types
Base * ptr; // pointer to base class
ptr = &dv1; //put address of dv1 in pointer
ptr->show(); // execute show
ptr = &dv2;
ptr->show();
return 0;
}

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 57 / 1
Polymorphisme

En POO, le polymorphisme est le fait que : les instances d’une sous-classe


soient substituables aux instances des classes de leur ascendance, en
argument d’une méthode ou lors d’affectations
La mise en œuvre se fait par :
les mécanismes de l’héritage dans les hiérarchies de classes,
la résolution dynamique des liens : le choix des méthodes à invoquer se fait
lors de l’exécution du programme en fonction de la nature réelle des instances
concernées

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 58 / 1
Résolution des liens

Une instance de sous-classe B est substituable à une instance de super-classe


A.
Que se passe-t-il lorsque B redéfinit une méthode de A ?
class A{
public:
void affiche(){cout << ”A” << endl;}
};
class B: public A{
public:
void affiche(){cout << ”B” << endl;}
};
int main(){
A aa;
B bb;
aa = bb;
aa.affiche();
}

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 59 / 1
Résolution des liens (2)

En C++, c’est le type de la variable qui détermine la méthode à exécuter .


Résolution statique des liens.
Ligature statique (early bending)
class A{
public:
void affiche(){cout << ”A” << endl;}
class B: public A{
public:
void affiche(){cout << ”B” << endl;}
int main(){
A aa;
B bb;
aa = bb;
aa.affiche();
}

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 60 / 1
Résolution dynamique des liens

Il pourrait dans certains cas sembler plus naturel de choisir la méthode


correspondante à la nature réelle de l’instance.
aa.affiche(); -> bb.affiche();
Dans ces cas, il faut permettre la résolution dynamique des liens : Le choix
de la méthode à exécuter se fait à l’exécution, en fonction de la nature réelles
des instances.

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 61 / 1
Méthodes virtuelles

En C++, on indique au compilateur qu’une méthode peut faire l’objet d’une


résolution dynamique des liens en la déclarant comme virtuelle (mot clé
virtual).
cette déclaration doit se faire dans la classe la plus générale qui admet cette
méthode (c’est-à-dire lors du prototypage d’origine)
les redéfinitions éventuelles dans les sous-classes seront aussi considérées
comme virtuelles par transitivité.
Syntaxe :
virtual Type nom fonction(liste d’arguments) [const];
Exemple :
class A {
virtual void afficher() const {
cout << ”A” << endl; }
};

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 62 / 1
Méthodes virtuelles (2)
class Base{
public:
virtual void affiche(){
cout << ”Base \ n”;
}};
class Derv : public Base{
public:
void affiche(){
cout << ”Derv \ n”;
}};
void F(Base t){
t.affiche();}
main(){
Base b;
Derv d;
F(b);
F(d);
}
Said Charfi (Associate Professor Department of Computer Science,
Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 63 / 1
Méthodes virtuelles (3)

Ici la méthode F prend un argument par valeur. Elle va donc s’exécuter sur
une copie de cet argument.
Il faut passer t par référence pour que la méthode F agisse sur l’instance
d’origine !
void F(Base & t){
t.affiche();
}
main(){
Base b;
Derv d;
F(b);
F(d);
return 0;
}

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 64 / 1
Méthodes virtuelles (4)

En résumé : Lorsqu’une méthode virtuelle est invoquée à partir d’une


référence ou d’un pointeur vers une instance, c’est la méthode associée au
type réel de l’instance qui sera exécutée.
Attention !
Un constructeur ne peut pas être virtuel
on ne peut pas invoquer de méthode virtuelle dans un constructeur (plus
exactement : l’aspect polymorphique est ignoré dans le constructeur, seule
l’instance correspondant à la classe courante est appelée)
il est conseillé de toujours définir les destructeurs comme virtuels

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 65 / 1
Méthodes virtuelles pures

Au sommet d’une hiérarchie de classe, il n’est pas toujours possible de :


donner une définition générale de certaines méthodes, compatibles avec toutes
les sous-classes,
...même si l’on sait que toutes ces sous-classes vont effectivement implémenter
ces méthodes

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 66 / 1
Méthodes virtuelles pures (2)

Une méthode virtuelle pure, ou abstraite, est incomplètement spécifiée :


elle n’a pas de définition dans la classe où elle est introduite (pas de corps)
elle sert à signaler aux sous-classes qu’elles doivent redéfinir la méthode
virtuelle héritée
Syntaxe :
virtual Type nom methode(liste d’arguments) = 0;

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 67 / 1
Méthodes virtuelles pures (3)

class Base{
public:
virtual void affiche()=0;
class Derv : public Base{
public:
void affiche(){
cout << ”Derv \ n”;
}
};

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 68 / 1
Classes abstraites

Une classe abstraite est une classe contenant au moins une méthode virtuelle
pure.
Elle ne peut être instanciée
Ses sous-classes restent abstraites tant qu’elles ne fournissent pas les
définitions de toutes les méthodes virtuelles pures dont elles héritent

Said Charfi (Associate Professor Department of Computer Science,


Programmation
Faculty of Science,
Orientée
University
Objets of Ibn Zohr Agadir, Morocco)
charfisaid@gmail.com 69 / 1

Vous aimerez peut-être aussi