• Aucun résultat trouvé

Les concepts de base de la POO

N/A
N/A
Protected

Academic year: 2022

Partager "Les concepts de base de la POO"

Copied!
10
0
0

Texte intégral

(1)

1

Plan – POO

„

Les concepts de base de la POO

„ Encapsulation / Classe

„ Héritage / Sous-Classes / Classes dérivées

„

Classes abstraites

„

Héritage multiple

„

Polymorphisme

2

Classes abstraites

„ Idée intuitive :

„ Une classe abstraite est une classe dans laquelle on a défini une (ou des méthodes) pour laquelle on a explicitement dit :

„Qu’elle ne sera pas implémentée.

„ L’implémentation de ces méthodes appelées méthodes virtuelles « pures » est laissée à la charge des classes dérivées.

„ On ne peut donc pas instancier des objets de cette classe, mais uniquement des classes dérivées qui auront implémentées ces méthodes virtuelles.

3

Classes abstraites

„

L’objectif d’une classe abstraite est de permettre la définition de profils de méthodes

„

Qui devront être implémentées dans toutes les classes dérivées.

„

Et donc de définir un « comportement » commun à un ensemble de classes dérivées.

4

Classes abstraites

„

Déclaration d’une méthode virtuelle pure :

„

virtual type nom (liste de paramètres) = 0;

„

Si une classe contient une méthode abstraite,

„ aucun objet de cette classe ne peut être manipulé.

„

Nécessité d'employer le mécanisme d'héritage et de spécialisation du descendant

„ pour définir le corps de la méthode

Classes abstraites

„ On considère par exemple la classe CElement qui possède une méthode de dessin qui n’est pas implémentée.

class CElement { …

virtual void Draw() = 0;

};

„ Chaque sous-classe doit spécifier cette implémentation.

„ La déclaration d'un objet de type CElement est incorrecte

„ CElement elem; // déclaration incorrecte

Classes abstraites

„ Description d’une classe dérivée CLine qui implémente la méthode abstraite « Draw »

class CLine : public CElement { ...

public : void Draw();

};

void CLine:: Draw () { // dessin de la ligne }

„ On peut alors déclarer des objets de type CLine

„CLine ligne; // déclaration correcte

(2)

7

Héritage multiple

„ Une classe peut dériver d’une ou plusieurs classes.

„ Supposons que l’on dispose :

„ d’une classe « CEnseignant »,

„ et d’une classe « CChercheur »

„ et l’on souhaite définir une classe dérivée :

« Enseignant_Chercheur »

CChercheur CEnseignant

Enseignant_Chercheur

8

Héritage multiple

„

On peut définir la classe Enseignant_Chercheur à l’aide du mécanisme de d’héritage multiple :

„ class Enseignant_Chercheur : public CEnseignant, public CChercheur

„

La classe Enseignant_Chercheur hérite des attributs et méthodes des classes CEnseignant et CChercheur.

9

Héritage multiple

„ La possibilité de définir des héritages multiples peut conduire à des ambiguïtés:

class CEnseignant { char grade[MAX];

...

public :

void lire_grade(char *); // méthode lire_grade };

class CChercheur { char grade[MAX];

...

public :

void lire_grade(char *); // méthode lire_garde(homonyne) };

class Enseignant_Chercheur : public CEnseignant, public CChercheur { ...};

10

Héritage multiple

„

Existence de méthodes des classes mères (« sur-classes ») qui ont des noms identiques.

„

L’ambiguïté peut être levée en précisant explicitement la classe mère considérée lors de l’appel

„

opérateur de résolution de portée (::)

Héritage multiple

„

Enseignant_Chercheur ec;

„

déclaration d’un “Enseignant_Chercheur”

„

ec.CEnseignant:: lire_grade(mot);

„

mot est le grade de l’enseignant

„

ec.CChercheur:: lire_grade(mot);

„

mot est le grade du chercheur

Héritage multiple

„ Une classe dérivée peut avoir dans ses ascendants plusieurs fois la même classe de base.

„ L’ambiguïté concerne le « partage » de la classe mère.

CChercheur CEnseignant

Enseignant_Chercheur CPersonne

(3)

13

Héritage multiple

„

Y-a-t-il un seul objet de la classe mère ou deux indépendants ?

„Pour obtenir un seul objet de la classe « mère », les classes dérivées « CEnseignant » et « CChercheur » peuvent être définies comme virtuelles :

„

class CEnseignant : public virtual CPersonne

„

class CChercheur : public virtual CPersonne

„lors de la définition de la classe

«Enseignant_Chercheur ».

14

Héritage multiple

„

Le rôle de “virtual” est de signaler au compilateur

„que les classes dérivées de ces classes virtuelles nécessitent un traitement spécial

„suppression des classes ancêtres “en double”

„

Un objet est alors vu comme :

„un unique objet de la classe “CPersonne”

„et les spécificités des classes “CEnseignant” et

“CChercheur”.

15

Polymorphisme

„

Le polymorphisme est un mécanisme puissant,

„ très utile dans la spécification d'une hiérarchie de classes.

„

L'idée intuitive est de permettre l'application d'une "même" opération à des objets différents.

„

La mise en oeuvre de cette propriété est réalisée par deux mécanismes en C++ :

„ la surcharge

„ l'édition de liens dynamique (ligature dynamique)

16

Polymorphisme

„

1 er cas : la surcharge

„

La surcharge offre la possibilité de définir

„

des méthodes homonynes

„(même nom et mêmes paramètres)

„

dans une classe et dans ses classes dérivées.

Polymorphisme

„

2 ème cas : la ligature dynamique

„

Ce mécanisme est encore plus puissant que la surcharge car il permet :

„en cas d'ambiguité sur le choix de la méthode homonyne à utiliser,

„de différer cette décision jusqu'au moment de l'appel de la méthode

„

Génération de tous les codes possibles,

„et décision lorsqu'on connaît la classe de l'objet à traiter

Polymorphisme

„ On considère tout d’abord une classe « CPersonnage ».

„ Un personnage représente un personnage d’un jeu.

„ Tous les personnages ont des caractéristiques communes comme un nom, des points de vie, une position courante, etc.

„ Et on dispose de méthodes pour

„ « dessiner » un personnage,

„ « effacer » un personnage

„ et aussi le « déplacer ».

(4)

19

Polymorphisme

class CPersonnage { protected :

char nom[30];

int posx, poy;

public

CPersonnage(); // construteur

void dessiner(); // méthode qui permet de dessiner à l’écran // le personnage à la position courante posx, poy void effacer(); // pour effacer le personnage à l’écran void deplacer(int, int); // pour effacer le personnage dessiné,

//changer sa position et le redessiner };

20

Polymorphisme

„

On souhaite définir une classe « CMagicien » dérivée de la classe « CPersonnage" .

„

Un magicien est spécialisé par rapport à un personnage par :

„ l'ajout de nouveaux attributs comme les

« sortilèges » qu’il possède …

„ l'ajout/surcharge des méthodes membres et notamment on souhaite pouvoir

„« dessiner », « effacer » et « deplacer » un magicien

21

Polymorphisme

class CMagicien : public CPersonnage { private :

char sortileges[10][30];

… public : CMagicien();

void dessiner () ; void effacer ();

}; ….

22

Polymorphisme

„ Pour dessiner un magicien, on suppose qu’il faut

„d’abord dessiner son personnage

„puis dessiner les caractéristiques spécifiques du magicien (chapeau, cape, …)

void CMagicien :: dessiner () { CPersonnage:: dessiner();

… // dessin des spécificités du magicien }

„ L’appel de la méthode de dessin du personnage est faite l’instruction :

„ CPersonnage ::dessiner();

Polymorphisme

„ De même pour effacer un magicien, on doit d’abord effacer son personnage puis effacer ses caractéristiques spécifiques (chapeau, cape, …)

void CMagicien :: effacer () {CPersonnage:: effacer();

… // « effacement » des spécificités du magicien }

„ L’appel de la méthode d’effacement du personnage est faite par l’instruction :

„ CPersonnage :: effacer();

Polymorphisme

„ La méthode « deplacer » de la classe CPersonnage effectue le traitement suivant :

„ Effacement du personnage à sa position courante

„ Modification de la position courante du personnage

„ Dessin du personnage à sa nouvelle position void CPersonnage :: deplacer ( int nx, int ny ) { effacer();

posx=nx; posy=ny;

dessiner();

}

(5)

25

Polymorphisme

„ Déplacer un magicien consiste à :

„ Effacer le magicien à sa position courante

„ Changer la position

„ Dessiner le magicien à la nouvelle position

„ Cette méthode est donc

„ « similaire » à la méthode définie pour un personnage

„ excepté qu’il faut utiliser les méthodes « dessiner » et

« effacer » de la classe dérivée CMagicien au lieu de celles de la classe CPersonnage.

„ La classe CMagicien hérite de la méthode « deplacer ».

26

Polymorphisme

„ On souhaite récupérer la méthode « deplacer » définie dans la classe CPersonnage

„ Cette méthode « deplacer » fait appel aux méthodes

« dessiner » et « effacer »

„ dont il existe deux versions homonymes sur les classes CPersonnage et CMagicien

„ Nécessité de s'assurer que ce sont bien les méthodes

« dessiner » et « effacer » de la classe CMagicien qui seront utilisées pour un magicien.

27

Polymorphisme

„ Le compilateur n'est pas en mesure de faire le choix car lors de la compilation,

„ on ne sait pas encore de façon précise lequel des descendants va demander l'exécution de la méthode « déplacer ».

„ Nécessité de différer le choix de l'homonyme à appeler

„ et prévoir tous les cas possibles.

„ On appelle ligature dynamique cette méthode de résolution d'appels.

28

Polymorphisme

„

Le choix qui a été fait en C++ est de demander à l'utilisateur :

„

de signaler par le mot clé virtual toute méthode

„

pour laquelle la ligature doit être dynamique.

„

On parle de méthodes virtuelles.

Polymorphisme

class CPersonnage /* deuxième version */

{ protected : char nom[30];

int posx, poy;

public

CPersonnage();

virtual void dessiner(); // méthode virtuelle virtual void effacer(); // méthode virtuelle void deplacer(int, int);

};

Polymorphisme

„ On pourra alors de façon transparente, utiliser « deplacer » sur un

« CPersonnage » ou sur un « CMagicien ».

CPersonnage perso;

perso.deplacer();

/* utilise les méthodes « dessiner » et « effacer » de personnage dans la méthode « deplacer » */

CMagicien mage;

mage.deplacer();

/* utilise les méthodes « dessiner » et « effacer » du magicien dans la méthode « deplacer » sans redéfinir cette méthode dans la classe CMagicien*/

„ Lors des appels, le compilateur va détecter le type d’objet réalisant l’appel et aller sélectionner la méthode adéquate.

(6)

31

Programmation avancée en C++

„

Rappel : passages de paramètres

„

La généricité (patrons)

„

Les exceptions

„

Les flots

32

Langage C++

Rappel : passages de paramètres

„

Il n’existe en langage C qu’un mode de passage des paramètres qui est

„

le mode lecture aussi appelé par valeur.

„

Pour faire une passage en écriture ou lecture/écriture i.e. par adresse, il faut le faire explicitement :

„

À la charge du programmeur

33

Langage C++

Rappel : passages de paramètres

„

Exemple 1 : Passage par valeur

„ On considère la fonction suivante : int addition(int x, int y)

{return x+y;} // les valeurs de x et y sont seulement « lues »

„Avec les définitions suivantes :

„int u=1, v=2, res;

„int *pu, *pv;

„pu = new int; *pu = 4; pv=&v;

„Les deux appels ci-dessous sont corrects

„res = addition(u,v);

„res= addition (*pu, *pv);

34

Langage C++

Rappel : passages de paramètres

„

Exemple 2 : Passage par adresse « explicite »

„ On considère la fonction suivante : void echange(int *px, int *py)

{int z; z= *px; *px= (*py); *py = z; }

// les valeurs pointées par px et py peuvent être « modifiées »

„Avec les définitions suivantes :

„int u=1, v=2, res;

„int *pu, *pv;

„pu = new int; *pu= 4; pv=&v;

„Les deux appels ci-dessous sont corrects

„echange(&u,&v);

„echange (pu, pv);

Langage C++

Rappel : passages de paramètres

„

Le langage C++ a introduit un mode de passage par référence

void echange(int & x, int & y)

{ int z; z=x; x=y; y=z;}

„

L’appel peut se faire sous la forme :

„int u=4, v=5;

„echange(u,v);

Langage C++

Rappel : passages de paramètres

„

Le langage C++ a conservé le mode de passage par valeur du langage C.

„

int addition(int x, int y)

„{ return x+y;}

„

L’appel peut se faire sous la forme

„int u=4, v=5, w ;

„w= addition(u,v);

(7)

37

Langage C++

Rappel : passages de paramètres

„ Lors un paramètre doit être passé en lecture (par valeur) et que son type n’est pas un type de base (int, float, …).

„ On peut utiliser une autre forme proposée par C++,

„ Qui consiste à faire une passage par référence mais en précisant que le paramètre effectif ne sera pas modifié

„ Économie d’espace et gain de vitesse

„ void echangePerso(const CPersonnage &p1, const CPersonnage &p2);

„ L’appel peut être fait sous la forme : CPersonnage perso1, perso2;

echange (perso1, perso2);

38

Généricité

„

Définir un modèle

„ de fonctionnement d'une fonction,

„ de définition d'une classe

qui puisse s'appliquer à différents types de données.

„

Par exemple, pour une pile d'objets

„ Les opérations de manipulation de la pile sont

"indépendantes" du type des objets manipulés

„empiler, dépiler, est_vide, sommet

39

Généricité

„

Le type des objets peut être

„simple : entier, caractère, …

„ou complexe : classe

sans influence sur le mode de fonctionnement de la pile

„

Généricité : avoir des outils qui permettent de manipuler des objets "formels"

„choix du type "effectif" lors de la déclaration de la pile

„instanciation du type générique

40

Généricité

„

Autre généricité souhaitée :

„possibilité de définir le fonctionnement d'une fonction

„sans utiliser le mécanisme de surcharge pour chaque type possible

„

Mais en la décrivant de façon "formelle"

„

Instanciation au moment de l'appel en fonction du type des paramètres effectifs utilisés

Généricité des fonctions

„ Exemple :

„ On souhaite définir une fonction qui retourne la valeur maximum de deux valeurs passées en paramètres.

„ utilisable sur tous les types de base int, char, float, double, etc...

„ 1ère solution :

„ Surcharger la fonction pour tous les types possibles

„ int max (int x, int y);

„ float max (float x, float y);

„ Solution lourde et peu satisfaisante

Généricité des fonctions

„ 2ème solution :

„ Définir "max" sur un type formel

„ Spécification d'un nom de type formel T

„ Utilisation de ce type formel pour décrire la fonction template <class T>

T max (T x, T y) { if (x > y)

return (x);

else return(y);

}

(8)

43

Généricité des fonctions

„ Utilisation de cette fonction paramétrée void main (void)

{ int u=5, v=6, w;

float s=5.7, f=7.8, g;

/* appel de max avec les entiers */

w= max (u,v);

cout << "max entier = " << w;

/* appel de max avec les réels */

g= max(s,f);

cout << "max réel = " << g;

}

44

Généricité des fonctions

„

Remarques

„

Le type T peut être un nom de type (ici int, float) ou de classe

„

T peut être un type prédéfini pour lequel l'opérateur de comparaison ">" est prédéfini

„

ou bien T peut être un type utilisateur pour lequel l'opérateur ">" a été surchargé

„

pas de limite grâce au mécanisme de surcharge des opérateurs

45

Généricité : les modèles de classe

„ Modèles de classe = classes génériques = patrons

„ Utilisation de la notion de type formel pour définir une classe générique.

„ Supposons par exemple définir une classe CEnsemble qui peut contenir n’importe quels types d’objets avec des fonctionnalités classiques

„ Ajout d’un élément

„ Suppression d’un élément

„ Test si un élément est dans l’ensemble

„ Union de 2 ensembles

„ Etc.

46

Généricité : les modèles de classe

„ Définition de la classe générique

„ T est le nom du type formel utilisé pour la définition de la classe template <class T>

class CEnsemble { private :

T tab[MAX];

// L’ensemble est géré par un tableau de MAX éléments de type T int nbe;

public : CEnsemble();

void ajout(T);

void supprime(T);

bool appartient(T);

};

Généricité : les modèles de classe

„ Définitions des différentes méthodes

„ rappel de la forme générale :

„ type_retour nom_classe :: nom_fonction (paramètres)

„ Ici, la classe est une classe générique il faut donc

„ Préciser le nom du paramètre formel utilisé pour la description de la méthode

„template <class T>

„ Donner le nom de la classe générique

„CEnsemble<T>

Généricité : les modèles de classe

„ Définition du constructeur : template <class T>

CEnsemble<T> :: CEnsemble() { nbe=0;}

„ Définition de la méthode « ajout » template <class T>

void CEnsemble<T> :: ajout (T elem) { if (nbe < MAX && ! appartient(elem))

tab[nbe++]=elem;

}

(9)

49

Généricité : les modèles de classe

„ Définition de la méthode « appartient » template <class T>

bool CEnsemble<T> :: appartient (T elem) { bool trouve = false;

int i=0;

while (i < nbe && !trouve)

if (tab[i] == elem) trouve=true;

else i++;

return trouve;

}

„ Cette méthode utilise l’opérateur == pour comparer 2 objets du type formel T

„ Il faudra que cet opérateur soit défini pour le type effectif utilisé pour instancier la classe CEnsemble, i.e.

„ Type de base (int, float, …)

„ Classe définie par l’utilisateur mais avec une surcharge de l’opérateur ==

50

Généricité : les modèles de classe

„

Utilisation de cette classe générique.

„

Instanciation du type formel par un type effectif à la déclaration d'un objet de cette classe

„

CEnsemble<int> ensEntier;

„ Instanciation du type T par le type int,

„ Déclaration de la variable ensEntier comme étant un ensemble d’entiers

„Le type int possède l’opérateur de comparaison ==

51

Généricité : les modèles de classe

„

Censemble<CPersonnage> ensPerso;

„ Instanciation du type T par le type CPersonnage,

„ Déclaration de la variable ensPerso.

„

Cette instanciation est correcte seulement si l’opérateur == a été défini dans la classe CPersonnage.

„ bool operator==(CPersonnage p);

52

Généricité : les modèles de classe

„ Le nombre de paramètres formels n'est pas limité à 1,

„ on peut en avoir plusieurs.

template <class X, class Y>

class Compose { private :

X attribut1;

Y attribut2;

public : ...

};

Généricité : les modèles de classe

„

Une classe peut être paramétrée

„

par "autre chose" qu'un type formel

„

par exemple une valeur qui représente une taille, ...

Généricité

Définition d'un buffer d'objets

„ Généricité sur le type des objets

„ Généricité sur la taille du buffer template <class T, int taille = 64>

/* 64 est la valeur par défaut de l'élément taille */

class Buffer { T *buf;

public : /* constructeur */

Buffer();

...

};

(10)

55

Généricité

Définition d'un buffer d'objets

„ Définition du constructeur qui alloue dynamiquement le buffer.

template <class T, int taille=64>

Buffer<T,taille> :: Buffer() { buf= new T [taille];

}

„ Le nom de la classe générique est Buffer<T,taille>

„ L’instruction buf= new T [taille] alloue un tableau de taille « taille » d’éléments de type T.

56

Généricité

Définition d'un buffer d'objets

„

Déclaration d'un objet de la classe

„

b est une variable de type Buffer avec une instanciation du type formel avec des entiers et une taille fixée à la valeur 100.

„

Buffer <int,100> b;

„

Tableau de 100 entiers,

„

réservation dynamique des éléments par appel du constructeur de la classe générique

57

Généricité - Conclusion

„

La généricité est un mécanisme qui permet :

„

De définir des méthodes ou des classes formelles manipulant des types d'objets

« généraux ».

„

Et de spécifier ces types lors de l'utilisation de

la classe ou de la méthode.

Références

Documents relatifs

En vertu de ses capacités à manipuler les données relationnelles, à créer des règles d’association permettant d’évaluer conjointement les caractéristiques des objets et

Meyerson précise qu’il ne vise pas le pan-algébrisme de l’école de Marburg, pourtant présenté comme la « forme la plus définie » d’idéalisme

The existence of spiral breakdown states is shown to proceed from a global instability of the axisymmetric breakdown solution to helical disturbances with azimuthal

The micro reading task consisted in extracting GO terms from a single MEDLINE abstract, as in the Trieschnigg et al’s work; the macro reading task consisted in extracting GO terms

Par exemple, pour d´eclarer une variable strNomDeFamille de type chaˆıne de caract`eres et lui attribuer la valeur ”Tavenard”, en VB, on a :. Dim strNomDeFamille as

La vitesse moyenne d’un mobile sur une distance et pendant une durée est une vitesse fictive vitesse fictive vitesse fictive vitesse fictive correspondant à la

Kramp , un nouvel instrument , suscep- tible sans doute de perfectionrierrient ; mais qui , tel qu’il est , peut déjà, dans un grand nombre de circonstances,