réutilisation ?

34
Programmation Objet en JAVA Cours 2 : Réutilisation, Héritage 1 Agrégation, composition, héritage, Hiérarchie, Constructeurs, Transtypage

Upload: lamis

Post on 04-Jan-2016

48 views

Category:

Documents


2 download

DESCRIPTION

Programmation Objet en JAVA Cours 2 : Réutilisation, Héritage 1 Agrégation, composition, héritage, Hiérarchie, Constructeurs, Transtypage. Réutilisation ?. Comment utiliser une classe comme matériau pour concevoir une autre classe répondant à de nouveaux besoins ? - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Réutilisation ?

Programmation Objet en JAVA

Cours 2 : Réutilisation, Héritage 1

Agrégation, composition, héritage, Hiérarchie, Constructeurs, Transtypage

Page 2: Réutilisation ?

Réutilisation ?

• Comment utiliser une classe comme matériau pour concevoir une autre classe répondant à de nouveaux besoins ?

• Quels sont les attentes de cette nouvelle classe ? – besoin des «services» d'une classe existante (les données

structurées, les méthodes, les 2). – faire évoluer une classe existante (spécialiser, ajouter des

fonctionnalités, ... )• Quelle relation existe entre les 2 classes ? • Dans une conception objet, des relations sont définies, des règles

d'association et de relation existent.

• Un objet fait appel un autre objet.• Un objet est crée à partir d'un autre : il hérite.

Page 3: Réutilisation ?

La relation client/serveur - Agrégation

• Un objet o1 de la classe C1 utilise un objet o2 de la classe C2 via son interface (attributs, méthodes).

• o1 délègue une partie de son activité et de son information à o2. • o2 a été construit et existe par ailleurs.• Faire une référence dans C1 vers un objet de C2; • Attention o2 est autonome, indépendant de o1, il peut être partagé. • C'est une agrégation.

public class C1 { private C2 o2; ...}

public class C2 { ... ...}

Le client Le serveur

Page 4: Réutilisation ?

La relation client/serveur - Agrégation

public class Cercle { private Point

centre; ...}

public class Point { ... ...}

Le client Le serveur

Page 5: Réutilisation ?

La relation client/serveur - Composition

• Mais si o2 évolue, est-ce grave?

• Comment faire pour que o1 possède son o2 à lui. • La solution se trouve dans le constructeur de C1 : doter o1 d'un objet

o2 qui lui appartienne.• C'est une composition.

public class C1 { private C2 o2; ... C1(...){

o2 = new C2(...); } ...}

public class C2 { ... ...}

Le client Le serveur

Page 6: Réutilisation ?

La relation client/serveur - Composition

public class Cercle { private Point

centre; ... public Cercle(...){

centre = new Point(...);

} ...}

public class Point { ... ...}

Le client Le serveur

Page 7: Réutilisation ?

L'exemple du cercle

• Le cercle c1 a un centre. C'est le point p1. • Utilisation d'un objet de type Point, car la classe existe déjà. • Si agrégation, tout changement effectué sur p1 a des conséquences

sur c1. – Si on déplace p1, on déplace tous les cercle ayant comme centre

p1. Composition ? • Mais plusieurs cercle peuvent partager le même centre ... Impossible

si composition. – ça se discute !

• Question : A-t-on besoin du code source de la classe Point pour coder la classe Cercle ?

• Besoin d’un objet existant ? « Se connecter à un serveur » • Confiance en l’encapsulation Agrégation

• Composition et getter.

Page 8: Réutilisation ?

Nouveau problème

• Si le serveur est insuffisant, incomplet, inadapté ?

– un objet Point répond à un besoin «mathématique».

– Si on veut en faire un objet graphique, avec une couleur et qu'il soit capable de se dessiner ?

– Mais en gardant les propriétés et les fonctionnalités d'un Point.• La solution en POO : l'héritage.

– Définir une nouvelle classe à partir de la définition d'une classe existante.

– Spécialiser, augmenter.

Page 9: Réutilisation ?

Héritage

public class LaClasseFille extends LaClasseMere{...}

class PointAvecUneCouleur extends Point

• En java, on n'hérite que d'une seule classe.

• Un objet de ClasseFille peut faire tout ce que sait faire un objet de ClasseMere

• Il le fait différemment et/ou il peut plus.

Page 10: Réutilisation ?

Exemple en Javadoc

Page 11: Réutilisation ?

Hiérarchie en Héritage

• L'héritage est une notion transitive

• Hiérarchie d'héritage : l'ensemble des classes dérivées d'un parent commun.

• Attention ce n'est pas bijectif :

– un Point3D est un Point.

– Le contraire est faux.

Chaîne d'héritage : le chemin menant d'une classe vers ses ancêtres.

Page 12: Réutilisation ?

Concept d’héritage

• Concept fondamental des langages objet. • Dériver une nouvelle classe à partir d'une classe existante en

récupérant ses propriétés.• Avantage

– Réutilisation : factorisation, enrichissement de champs et méthodes de classes existantes.

– Spécialisation d’une classe existante sans la modifier.– Pas de limitation en profondeur.

• Contrainte– Héritage simple : une classe ne peut hériter que d'une

seule classe.– Toutes les méthodes et champs ne sont plus regroupées

dans le même fichier

Page 13: Réutilisation ?

Exemple d'héritage

import Point;public class PointAvecUneCouleur extends Point{ int couleur, x, y; // x et y sont hérités public PointAvecUneCouleur(int couleur) // un

constructeur { super(); // appel au constructeur de la classe mère setCouleur(couleur); } public PointAvecUneCouleur(int x, int y, int couleur) // un

constructeur {

super(x,y); // appel au constructeur de la classe mèresetCouleur(couleur);

} public void setCouleur(int couleur) { this.couleur=couleur; // désigne l'objet encours }

Page 14: Réutilisation ?

La classe "Object"

• Toutes les classes Java sont des descendants de la classe Object.• Object est parent par défaut des classes qui ne précisent pas leur ancêtres • Object offre quelques services génériques dont la pluspart sont à refaire, ...

à redéfinir (attention au fonctionnement par défaut) :

public final Class getClass(); • Renvoie un objet de type Class qui permet de connaître le nom d'une

classepublic boolean equals(Object o);

• Compare les champs un par un (pas les pointeurs mémoire comme ==)protected Object clone();

• Allocation de mémoire pour une nouvelle instance d'un objet et recopie de son contenu

public String toString(); • Renvoie une chaîne décrivant la valeur de l'objet

Page 15: Réutilisation ?

La classe "Class"

• C'est la classe qui identifie les types à l'exécution• Permet la sélection des méthodes en fonction de la classe

lors des appels

public String getName(); • Renvoie le nom d'une classe

public static Class forName(String s); • La fonction réciproque de getName

public Object newInstance(); • Crée une nouvelle instance de même type

public String toString(); • Renvoie une chaîne décrivant la valeur de l'objet

Page 16: Réutilisation ?

La méthode equals()

• Egalité entre objet et non entre référence

• Très utile pour les String– If (myString == "Hello") {…} Toujours Faux !!!– If (myString.equals("Hello") ) {…} OK

• Si les 2 objets o1 et o2 ont des références r1 et r2 comme champs, il faut que r1==r2 pour que o1.equals(o2) et non pas que r1.equals(r2)

• Réflexive, symétrique, transitive et consistent

• Pour les classes que vous créez, vous êtes responsable.

Point p1 = new Point(2,1);Point p2 = new Point(2,1);if (p1==p2){...} // Ici c'est fauxif (p1.equals(p2)){...}// OK si equals est bien redéfinitp1 = p2 // Co-référence if (p1==p2){...} // Vrai désormais

Page 17: Réutilisation ?

Les fonctions hashCode() et toString()

• hashCode() renvois un chiffre différent pour chaque instance différente• Si o1.equals(o2) alors o1.hashCode()==o2.hashCode()• Le contraire n’est pas assuré mais préférable (@mémoire)• Très utile pour les HashTable.

• toString() conversion en String d'un objet :

String s = '' mon objet visible '' + monObjet;

String s = '' mon objet visible '' + monObjet.toString();

Page 18: Réutilisation ?

Constructeurs et héritage

● L'héritage permet la réutilisation de code. Le constructeur est concerné. ● Possibilité d'invoquer une méthode héritée : la référence super.● Invocation d'un constructeur de la super-classe :

● super(<params du constructeur>)● L'utilisation de super ressemble à celle de this.● L'appel à un constructeur de la super classe doit toujours être la

première instruction dans le corps du constructeur.● Si ce n'est pas fait, il y un appel implicite : super(). ● Lors de la création d'un objet, les constructeurs sont invoqués en

remontant de classe en classe la hiérarchie, jusqu'à la classe Object. ● Attention, l'exécution se fait alors en redescendant dans la hiérarchie.

● Un constructeur d'une classe est toujours appelé lorsqu'une instance de l'une de ses sous classes est créée.

Page 19: Réutilisation ?

Héritage et constructeurs - suite

public class Point extends Object{ public Point(double i, double j) {...}}

public class PointAvecUneCouleur extends Point{ public PointAvecUneCouleur(int i, int j, int c){ super(i,j);

couleur=c; }

public class Object{ public Object() {...}}

Page 20: Réutilisation ?

Retour sur protected

• Dans la classe Point pour setX on a 3 possibilité :

• public : un objet PointAvecUneCouleur peut fixer l'abscisse, ... mais aussi tout le monde.

• private : plus personne ne peut, y compris un objet PointAvecUneCouleur.

• protected : la solution ici, les objets d'une classe héritière ont accès aux membres protected (+friendly).

public void setX (double nouveauX){...} private void setX (double nouveauX){...} protected void setX (double nouveauX){...}

Page 21: Réutilisation ?

Transtypage et héritage : surclassement.

• Le transtypage consiste à convertir un objet d'une classe en objet d'une autre classe

• Vers une «super-class» (upcast ou surclassement), c'est toujours possible : on peut toujours transtyper vers une super-classe, plus pauvre en informations.

Point3D unPoint3D = new Point3D( x, y, z );Point unPoint = (Point) unPoint3D; // une projection sur xOy

• La mention du transtypage est facultative, mais recommandée pour la lisibilité.

• « un Point3D est un Point mais pas le contraire. »• Un message envoyable à un objet, l'est aussi pour tous les objets d'une

classe héritière :

PointAvecUneCouleur p = new PointAvecUneCouleur();

p.translater(1,3); // Méthode définit au niveau de Point

Page 22: Réutilisation ?

Transtypage et héritage : surclassement.

• Le transtypage consiste à convertir un objet d'une classe en objet d'une autre classe

• Vers une «super-class» (upcast ou surclassement), c'est toujours possible : on peut toujours transtyper vers une super-classe, plus pauvre en informations.

Point3D unPoint3D = new Point3D( x, y, z );Point unPoint = (Point) unPoint3D; // une projection sur xOy

• La mention du transtypage est facultative, mais recommandée pour la lisibilité.

• Attention : unPoint3D est de type Point3D mais aussi Point. • « un Point3D est un Point mais pas le contraire. »• Un message envoyable à un objet, l'est aussi pour tous les objets d'une

classe héritière :

PointAvecUneCouleur p = new PointAvecUneCouleur();

p.translater(1,3); // Méthode définit au niveau de Point

Page 23: Réutilisation ?

Transtypage et héritage : sous-classement

• Le comportement d'un objet «hérité» est augmenté par rapport à un objet d'une classe mère. 

• Le transtypage vers une sous-classe (downcast ou sous-classement)– Impossible (sauf si un surclassement avait été fait)– pour transtyper vers une sous-classe, utiliser le mot-clé réservé

instanceof.unPoint = new Point3D(...);....if( unPoint instanceof Point3D) { unPoint3D = (Point3D) unPoint; unPoint3D.projection3D(...);}

• La mention du transtypage est obligatoire, dans ce cas.

Page 24: Réutilisation ?

Un exemple : la banquise

• Un plateau composé de 8x8 cases

– Les 4 coins : terre ferme

– les autres cases : banquise. Lorsqu’un joueur fait fondre une case banquise, les propriétés se révèlent :

• certaines cases ne fondent pas et fait apparaître un renard

• d’autres fondent font apparaître de l’eau et un banc de poissons ou ours

• d’autres donnent au joueur des capacités (elles sont donc garder par le joueur)

• d’autres implique une action immédiate (dérive)

• Pour résumer : deux grande familles de Cases, action et modification du joueur.

• Sur une case, peuvent être posés des pions et des igloos.

Page 25: Réutilisation ?

banquise : questions

• Comment encoder la notion de plateau ? • Comment encoder la notion de pion, igloo et des différentes actions

possibles ?• Pour les cases :

– Un type d’objet (sa classe) se définit par sa structure de données et son comportement.

– Si deux objets ont des comportements différents, ils appartiennent à deux types différents -> des classes différentes.

– Ce qui est générique à tous : peut contenir des pions et igloos

– Il y a plusieurs types de banquises, toutes ont une action lors de la fonte.

Page 26: Réutilisation ?

banquise : conception

Case // Contient Pions et Igloos sous forme de vecteurs

| // -> agrégation ou composition ?

|

|--- BanquiseFerme // la tuile change de forme, mais il ne

| // se passe rien.

|--- BanquiseAction // la fonte déclenche une action

| // du joueur -> lui envoie un

| // message spécifique

|--- BanquiseCapacité // la fonte modifie le joueur // -> lui envoie un message

spécifique

• Toutes les banquises sont des cases.• Toutes les cases banquises ont une méthode action.• Cette méthode est différente selon le type de la case (sa classe). • Le plateau est un tableau de Cases

Page 27: Réutilisation ?

Référence sur une Case

Vector<Pion> pions;

Igloo igloo;

...

Vector<pion> getPions();

boolean addPion();

boolean addIgloo();

boolean equals(Object o);

String toString();

Objet Case en mémoire@0ffa88

Case macase = new Case ( ... );

macase

Page 28: Réutilisation ?

Référence sur une BanquiseFerme

Vector<Pion> pions;

Igloo igloo; ...

Vector<pion> getPions();

boolean addPion();

boolean addIgloo();

boolean equals(Object o);

String toString();

Objet BanquiseFerme en mémoire

@0ffa98

BanquiseFerme macase =

new BanquiseFerme(...);

macase

public BanquiseFerme extends Case

void action( ... );

Page 29: Réutilisation ?

Surclassement d’une BanquiseFerme

@0ffa98

Case macase = new BanquiseFerme(null,1);

macase

Code hérité de la classe Case

public BanquiseFerme extends Case

Vector<Pion> pions;

Igloo igloo;

Vector<pion> getPions();

boolean addPion();

boolean addIgloo();

boolean equals(Object o);

String toString();

Objet BanquiseFerme en mémoire

void action( ... );

Page 30: Réutilisation ?

Surcharge et redéfinition (overload vs override)

public class Point { ... public void maMethode(int i){...}}

public class PointCouleur { ... public void maMethode(int i){...}}

public class Point3D { ... public void maMethode(double i){...}}

RedéfinitionSurcharge

Pour un objet Point3D :• 2 méthodes maMethode

Pour un objet PointCouleur :• une seule maMethode

Page 31: Réutilisation ?

Redéfinition et surclassement

Vector<pion> getPions();

boolean addPion();

boolean addIgloo();

Objet BanquiseFerme en mémoire

@0ffa98

Case macase = new BanquiseFerme(...);

System.out.println(macase);

macase

public Case {...public String toString(){

return « TerreFerme »;}

}public BanquiseFerme extends Case{

...public String toString(){

return « BanquiseFerme »;}

}

void action();

String toString();

Code hérité de la classe Case

Vector<Pion> pions;

Igloo igloo;

Page 32: Réutilisation ?

Exemple animalier

Animal

Cheval OursTortue

mangerdormirmarchercourir (2 x marcher)espèce

galopercourir hiberner

Cheval de courseCheval de traie

galopergaloper

Page 33: Réutilisation ?

Blocage de l'héritage

• Mot-clé final– Le mot-clé final devant une classe indique qu'elle ne peut avoir de

descendance.final class Point3D { ...}• Avantage

– Efficacité : implémentation statique possible.– Sécurité : pas de redéfinition possible des méthodes pour une

descendance.• Inconvénients

– Impossibilité de sous-classer pour créer une classe de test indépendante

Page 34: Réutilisation ?

Conseils de conception

• Faire des schémas

– Représentant les classes et leur hierarchie• Pour comprendre les interactions entre les classes (qui

a besoin d’une référence sur qui)• Pour savoir ou placer une fonction• Pour bien penser les droits d'accès

– Représentant les appels de fonction• Pour savoir quels objets sont traversés• Pour savoir où récupérer les données à mettre en

argument

• Attention l'héritage n'est pas une réponse à tout, la délégation est aussi utile.

– l'héritage est une relation is-like.