cpo 2002 - cours 4 page 1 conception et programmation à objets cours 4 interfaces et sous-typage...

20
CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface Définir une interface Définir les sous-types de l'interface Utiliser une interface Créer des instances des sous- types

Upload: aline-guyon

Post on 03-Apr-2015

102 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 1

Conception et Programmation à Objets

Cours 4Interfaces et Sous-Typage

Mikal Ziane

• Trop de classes

• Programmez vers une interface

• Définir une interface

• Définir les sous-types de l'interface

• Utiliser une interface

• Créer des instances des sous-types

Page 2: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 2

Gestion d’un IUT

• On veut créer un logiciel de gestion des personnes de l’IUT pour :– leur envoyer par email les informations les concernant

– éditer divers annuaires...

• Plusieurs sortes de personnes à l’IUT :– Etudiants de diverses formations

– Enseignants de différentes catégories

– Administratifs

– Techniciens

• Quelles classes définir ?

Page 3: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 3

Trop de classes

• Nombreuses sortes de personnes => trop de classes

• Traitements similaires mais pas identiques (sinon une seule classe).

Programme trop difficile à écrire Programme trop difficile à maintenir

si on ajoute ou ôte une sorte de personne

• SOLUTION :

cacher les classes derrière une INTERFACE

Page 4: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 4

Programmez vers une interface

• Principe fondamental pour faciliter la maintenance des programmes :

• Conséquence 1 : encapsulation

• Conséquence 2 : cacher les classes qui implémentent une interface

Programmez vers une interface pas vers une implémentation

Page 5: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 5

Interface• Interface : ensemble de prototypes de fonctions• Comment définir une interface ?

• En Java : définir directement une interface !• En C++ : définir une classe

– seulement la partie publique– pas de données=> constructeur facultatif– normalement pas de code pour les méthodes=> méthodes virtuelles pures

• Parfois on a besoin de définir du code pour une méthode=> méthode virtuelle mais "pas pure"

• Par contre : évitez de définir des données

Page 6: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 6

class Personne {public:

virtual const char* prenom() const =0; virtual const char* nom() const =0;};ostream& operator<<(ostream&, const Personne&);

virtual indique que la méthode va s'adapter automatiquement en fonction du genre de personne !

• =0 remplace le code de la méthode (qui doit alors absolument être virtual) !

• Coder les méthodes non pures et les fonctions extérieures à la classe.

• Exercice : comment operator<< peut-il s'adapter selon le genre de la personne ?

Page 7: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 7

Solution

class Personne {public:

virtual const char* prenom() const =0; virtual const char* nom() const =0;

virtual void afficher (ostream&) const =0 ;};ostream& operator<<(ostream&, const Personne&);

• operator<< est pratique mais ne peut pas être virtuel (extérieur à la classe).• Astuce : il appellera une méthode virtuelle qui peut donc s'adapter au genre de personne !

Page 8: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 8

// personne.cpp

#include "personne.hpp"

ostream& operator<< (ostream& os,

const Personne& p)

{ p.afficher(os);

return os;

}

Page 9: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 9

Sous-types d'une interface

• Il faut définir les sous-types de l'interface.

• Pour l'interface Personne : Enseignant, Etudiant...

• L'application "gestion des personnes de l'iut", ne doit pas voir ces sous-types : ils "implémentent" l'interface.

• En Java on peut dire directement qu'une classe implémente une interface.

• En C++ on utilise un concept fourre-tout : l'héritage.

• Attention une classe hérite de 3 choses :– de l'interface : très utile

– du code des méthodes : parfois utile

– des données : parfois utile mais dangereux !

Page 10: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 10

Personne

Enseignant Etudiant

Hiérarchie des personnes

Page 11: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 11

class Etudiant : public Personne {public: Etudiant (const char *p = "inconnu",

const char *n = "inconnu", int annee = 1 );

const char* prenom() const; const char* nom() const; int annee () const; void afficher (ostream&) const;private: Chaine nom_, prenom_; int annee_;};

héritage

Page 12: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 12

Définir un sous-type

• Deux cas :– le sous-type est aussi une interface

– le sous-type est une classe

• On indique l'héritage par : public

• Une classe doit donner le code des prototypes virtuels purs hérités.

• Sinon elle n'a pas le droit de créer d'instance : classe abstraite.

• Une classe abstraite est à mi-chemin entre une classe concrète et une interface.

Page 13: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 13

Conséquences du sous-typage

• Un pointeur déclaré comme Personne* peut pointer sur un Etudiant (idem pour les références).– type statique du pointeur : Personne*

– type dynamique du pointeur : Etudiant* ou Enseignant* ...

• Un paramètre Personne accepte aussi un Etudiant.• Les méthodes de la classe Personne peuvent être appliquées

sur les objets, pointeurs ou références de type Etudiant.• De façon générale un Etudiant est une Personne donc

partout ou une Personne est attendue un Etudiant peut aller.• Attention : ça ne marche pas à l'envers !• Une Personne n'est pas forcément un Etudiant !

Page 14: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 14

Utiliser un interface

• On ne voit pas les sous-types !

• Impossible de créer instances directes de l'interface :

Personne p ("jean","dupont"); // interdit utiliser des pointeurs ou références sur l'interface utiliser les méthodes virtuelles qui s'adaptent en fonction

du type de l'objet pointé (type dynamique du pointeur).

Personne* p = ...;

// pointer sur un etudiant ou un enseignant

cout << p->nom() << endl;

// nom() est virtuelle et la bonne version sera utilisée

Page 15: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 15

Créer les instances des sous-types

• Paradoxe : on doit créer une instance d'un sous-type qu'on ne connaît pas !

• Un module spécial, une usine (factory), pourrait créer les instances de l'interface et les autres modules les utiliser.

• Ainsi seule l'usine doit être modifiée si on ajoute ou enlève un sous-type.

• Mieux : une méthode spéciale de l'interface permet de créer les objets.

• Encore mieux : utiliser un design pattern (Prototype notamment).

• Exercice : comment définir cette méthode spéciale ?

Page 16: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 16

Méthode spéciale de création

class Personne {

public:

//...

static Personne* creer();

};• Static indique que la méthode n'a pas de paramètre this.

• Sinon il faudrait déjà disposer d'une instance pour pouvoir créer une instance !

• On pourrait aussi utiliser une fonction extérieure à la classe.

Page 17: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 17

void main (){ int n; cout << "nombre de personnes : "; cin >> n; if (n<=0) return; Personne** personnes = new Personne* [n]; for (int i=0; i<n; i++) personnes[i] = Personne::creer(); for (i=0; i<n; i++) cout << *personnes[i] << endl;}

• Pas besoin d'instance pour appeler une méthode statique.

Page 18: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 18

Personne* Personne::creer(){ cout << "creer un etudiant (1) ou un enseignant (2) ?" << endl; cout << "> "; int choix; cin >> choix; switch (choix) { case 1 : return Etudiant::creer(); case 2 : return Enseignant::creer(); default : cout << "choix incorrect" << endl; } return 0; // indique que la creation a echoue}• Idéalement il faudrait que cette fonction ne connaisse pas les sous-types non plus.• C'est possible ! Voir le design pattern Prototype.

Page 19: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 19

//etudiant.hppclass Etudiant : public Personne {public: // ... static Etudiant* creer();};

// etudiant.cpp Etudiant* Etudiant::creer(){ char prenom [100], nom[100]; int annee; cout << "prenom : "; cin >> prenom; cout << "nom : "; cin >> nom; cout << "annee : "; cin >> annee; return new Etudiant(prenom, nom, annee);}

Page 20: CPO 2002 - Cours 4 page 1 Conception et Programmation à Objets Cours 4 Interfaces et Sous-Typage Mikal Ziane Trop de classes Programmez vers une interface

CPO 2002 - Cours 4

page 20

Exercice (TD)

• On veut créer un éditeur graphique permettant de dessiner et manipuler divers objets graphiques : cercles, triangles ...

• Un cercle est déterminé par son centre (un point) et son rayon.

• Un triangle est déterminé par trois points.

• Ecrivez le main() ainsi que l'interface principale et la partie publique de la classe Cercle.