1 / 34

Réutilisation ?

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 ?

lamis
Télécharger la présentation

Réutilisation ?

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  2. 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.

  3. 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. • o2a é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. Le client Le serveur public class C1 { private C2 o2; ... } public class C2 { ... ... }

  4. La relation client/serveur - Agrégation Le client Le serveur public class Cercle { private Point centre; ... } public class Point { ... ... }

  5. 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. Le client Le serveur public class C1 { private C2 o2; ... C1(...){ o2 = new C2(...); } ... } public class C2 { ... ... }

  6. La relation client/serveur - Composition Le client Le serveur public class Cercle { private Point centre; ... public Cercle(...){ centre = new Point(...); } ... } public class Point { ... ... }

  7. 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.

  8. 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.

  9. 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.

  10. Exemple en Javadoc

  11. 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.

  12. 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

  13. Exemple d'héritage import Point; public classPointAvecUneCouleurextendsPoint { 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ère setCouleur(couleur); } public void setCouleur(int couleur) { this.couleur=couleur; // désigne l'objet encours }

  14. 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 classe public 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

  15. 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

  16. 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 faux if (p1.equals(p2)){...}// OK si equals est bien redéfinit p1 = p2 // Co-référence if (p1==p2){...} // Vrai désormais

  17. 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();

  18. 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.

  19. Héritage et constructeurs - suite public class Point extends Object { public Point(double i, double j) {...} } public class Object { public Object() {...} } public class PointAvecUneCouleur extends Point { public PointAvecUneCouleur(int i, int j, int c){ super(i,j); couleur=c; }

  20. 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){...}

  21. 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

  22. 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

  23. 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.

  24. 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.

  25. 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.

  26. 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

  27. Référence sur une Case @0ffa88 Objet Case en mémoire Vector<Pion> pions; Igloo igloo; ... Vector<pion> getPions(); boolean addPion(); boolean addIgloo(); boolean equals(Object o); String toString(); macase Case macase = new Case ( ... );

  28. Référence sur une BanquiseFerme @0ffa98 Objet BanquiseFerme en mémoire public BanquiseFerme extends Case Vector<Pion> pions; Igloo igloo; ... BanquiseFerme macase = new BanquiseFerme(...); Vector<pion> getPions(); boolean addPion(); boolean addIgloo(); boolean equals(Object o); String toString(); macase void action( ... );

  29. Surclassement d’une BanquiseFerme @0ffa98 Objet BanquiseFerme en mémoire public BanquiseFerme extends Case Vector<Pion> pions; Igloo igloo; Case macase = new BanquiseFerme(null,1); Vector<pion> getPions(); boolean addPion(); boolean addIgloo(); boolean equals(Object o); String toString(); Code hérité de la classe Case macase void action( ... );

  30. Surcharge et redéfinition (overload vs override) public class Point { ... public void maMethode(int i){...} } Surcharge Redéfinition public class Point3D { ... public void maMethode(double i){...} } public class PointCouleur { ... public void maMethode(int i){...} } Pour un objet Point3D : • 2 méthodes maMethode Pour un objet PointCouleur : • une seule maMethode

  31. macase Redéfinition et surclassement public Case { ... public String toString(){ return « TerreFerme »; } } public BanquiseFerme extends Case{ ... public String toString(){ return « BanquiseFerme »; } } @0ffa98 Objet BanquiseFerme en mémoire Vector<Pion> pions; Igloo igloo; Vector<pion> getPions(); boolean addPion(); boolean addIgloo(); Code hérité de la classe Case String toString(); Case macase = new BanquiseFerme(...); System.out.println(macase); void action();

  32. Exemple animalier manger dormir marcher courir (2 x marcher) espèce Animal Tortue Cheval Ours courir galoper hiberner Cheval de traie Cheval de course galoper galoper

  33. 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

  34. 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.

More Related