210 likes | 368 Views
Java : un langage Orienté Objet. LES CONCEPTS de L’ORIENTE OBJET :. L’héritage ou la dérivation introduction au concept d’héritage. hérite de la classe A. Accès direct à toutes les propriétés de A ( comme si elles avaient été déclarées dans B ). Classe A A::Prop 1 A::Prop 2
E N D
Java : un langage Orienté Objet LES CONCEPTS de L’ORIENTE OBJET : • L’héritage ou la dérivation • introduction au concept d’héritage Cours JAVA / Y.Laborde
hérite dela classe A • Accès direct à toutes les propriétés de A ( comme si elles avaient été déclarées dans B ) Classe A A::Prop 1 A::Prop 2 … • Masquage de la propriété 2 : A::Prop 2 => B::prop 2 Java : un langage Orienté Objet L’HERITAGE ou LA DERIVATION L’HERITAGE est un concept qui met en relation deux classes de telle sorte que : • la classe qui hérite acquiert automatiquement l’ensemble des propriétés de l’autre (sauf ses constructeurs) • de nouvelles propriétés peuvent être ajoutées (qui spécialisent la classe qui hérite) • des propriétés héritées peuvent être masquées pour être redéfinies en partie (cas où elles ne conviendraient pas totalement) class B extends class A { • nouvelles propriétés } Cours JAVA / Y.Laborde
class VectDominos class MainJoueur class Pioche class LigneDeJeu Java : l’héritage (ou la dérivation) LA RELATION DE DERIVATION est l’inverse de la relation d’héritage : (A hérite de B) (B est dérivé en A) (B est hérité par A) (A dérive B) Toutes ces relations sont équivalentes LA RELATION D’HERITAGE entre deux classes exprime que : la classe qui hérite « EST UNE SORTE DE » la classe héritée java.util.ArrayList<E> est une classe de l’API Java qui représente une liste admettant des éléments de classe <E> fixé à la construction. Ex: new ArrayList<Domino>() construit une liste vide dont les éléments seront des dominos. Exemples : (depuis Java 5) class ArrayList <Domino> C’est la classe de l’API Java (package java.util)qui est un vecteur admettant des éléments de classe Object class Vector Un vecteur de dominos est une sorte devecteurmais n’admettant que des éléments de classe Domino (utile pour ne plus avoir à faire de « cast ») Une main de joueur est une sorte deliste de dominos permettant en plus de les classer par marques Une pioche est une sorte deliste de dominos permettant en plus de piocher aléatoirement un domino. Une ligne de jeu est une sorte deliste de dominos permettant en plus l’ajout de dominos à droite et à gauche. Une main de joueur est une sorte devecteur de dominos permettant en plus de les classer par marques Une pioche est une sorte devecteur de dominos permettant en plus de piocher aléatoirement un domino. Une ligne de jeu est une sorte devecteur de dominos permettant en plus l’ajout de dominos à droite et à gauche. Cours JAVA / Y.Laborde
Exemple : class Object class Couleur class ArrayList<Domino> class Domino class Employé class Point class PointCouleur class Directeur class Secrétaire class Commercial class Pioche class Main class LigneDeJeu Java : l’héritage (ou la dérivation) • LA RELATION D’HERITAGE organise les classes en un ARBRE • En Java, l’héritage est dit SIMPLE car une classe ne peut pas hériter de plusieurs autres (auquel cas l’héritage serait dit MULTIPLE) • En Java, la racine de l’arbre est la classe java.lang.Object • Les relations inter-packages peuvent passer par des relations d’héritage Cours JAVA / Y.Laborde
Java : l’héritage (ou la dérivation) Dans la réalité, la relation d’héritage répond à plusieurs cas d’utilisation : (liste non exhaustive) • cas où une classe apparaît clairement pouvoir s’appuyer sur les propriétés d’une autre(ex : la classe PointCouleur apparaît pouvoir supporter les propriétés de la classe Point) • cas où plusieurs classes dévoilent clairement des propriétés communes particulières(ex : les classes Directeur, Secrétaire et Commercial contiennent toutes des propriétés identifiant une qualité d’employé, d’où l’idée de les faire hériter d’une classe Employé) • cas où il y a un intérêt à ce que plusieurs classes partagent des propriétés communes générales(sans que cela soit forcément évident à priori)(ex : toutes les classes de Java héritent des propriétés d’une classe de base nommée java.lang.Object, d’où il devient possible de définir des messages compris par toutes les classes) • cas où il y a un intérêt à ce que plusieurs classes puissent être modélisées sur la base d’une classe commune héritée qui, ne contenant aucune propriété implémentée spécifiquement, obligerait seulement les classes dérivées à les implémenter(ex : les classes entièrement abstraites de l’API Java ; ex: la classe java.awt.Component) Cours JAVA / Y.Laborde
Java : un langage Orienté Objet LES CONCEPTS de L’ORIENTE OBJET : • L’héritage ou la dérivation • introduction au concept d’héritage • discussion : « faut-il hériter ou encapsuler ? » Cours JAVA / Y.Laborde
Ou pour être plus proche du concept de dominos : • void addDomino (Domino) • Domino dominoAt (int) • int nombreDominos ( ) Java : un langage Orienté Objet Discussion : « faut-il hériter ou encapsuler ? » • HERITER revient à exprimer « EST UNE SORTE DE » • ENCAPSULER revient à exprimer « A UN » ou encore « POSSEDE UN » Or en théorie, ces deux types de relations sont interchangeables. En effet, il est toujours possible, pour un même cas, d’utiliser l’une ou l’autre mais les conséquences seront différentes, d’où la nécessité de savoir effectuer le bon choix. Cas 1 : Concernant la classe VectDominos, ce que l’on désire avant tout est une classe à l’image de Vector mais capable de n’admettre que des instances de classe Domino et non de classe Object, soit possédant (au minimum) les méthodes suivantes : • void addElement (Domino) • Domino elementAt (int) • int size ( ) La différence entre l’héritage et l’encapsulation ne porte ici que sur la méthode int size( ) dont on pourrait faire l’économie d’écriture grâce à l’héritage (car les autres méthodes devront obligatoirement être ajoutées). Cours JAVA / Y.Laborde
E N C A P S U L A T I O N H E R I T A G E classVectDominos { private java.util.Vector v; public VectDominos ( ) { v = new Vector ( ); } void addDomino (Domino d) { v.addElement (d); } Domino dominoAt (int i) { return (Domino) v.elementAt (i); } int nombreDominos ( ) { { return v.size ( ); } } class VectDominos extendsVector{ void addDomino (Domino d) { super.addElement (d); } Domino dominoAt (int i) { return (Domino) super.elementAt (i); } } Ici, dans un objet VectDominos il sera possible d’ajouter soit des dominos comme prévu, soit des objets quelconques car la méthode héritée public void addElement (Object) ne peut être interdite. Java : un langage Orienté Objet Cas1: Implémentation de la classe VectDominos par héritage ou encapsulation d’un Vector : CAS 1: Une bonne règle pour répondre à la question du choix consiste donc à : Ne choisir l’héritage que lorsquetoutes les méthodes héritées sont supportables par la nouvelle classe dérivée.En dehors de cela, toujours préférer l’encapsulation. Cours JAVA / Y.Laborde
Java : un langage Orienté Objet Cas 2 : Concernant les classes Directeur, Secrétaire et Commercial, ce qui apparaît avant tout est de faire émerger une qualité commune, Employé, disposant par elle-même de caractéristiques et comportements propres. Cette qualité commune étant ainsi pressentie comme pouvant être « factorisée » grâce à l’héritage. Dans ce cas, le problème est différent car la classe Employéest extraite des classes pressenties dérivées. Cette classe ne correspondra donc qu’à une factorisation de qualités communes et elle sera développée pour être spécifiquement dérivée en Directeur, Secrétaire,Commercial, etc. En général, ce genre de classe relève d’une qualité non terminale car incomplète vis-à-vis des entités de l’application. En ce sens, il apparaît évident qu’aucune instance d’Employé ne devrait exister puisque tout personnel est avant tout soit un Directeur, soit un Secrétaire, etc. CAS 2: Dans ce cas, l’héritage est parfaitement adapté. Il est même incontournable relativement aux notionsde classes apparentes et de liaison retardées vues plus loin. Cours JAVA / Y.Laborde
Java : un langage Orienté Objet LES CONCEPTS de L’ORIENTE OBJET : • L’héritage ou la dérivation • introduction au concept d’héritage • discussion : « faut-il hériter ou encapsuler ? » • classes vraies et classes apparentes Cours JAVA / Y.Laborde
Exemple : class Object class Employé class Directeur class Secrétaire Objet sec1 class Commercial Java : un langage Orienté Objet Classes vraies et classes apparentes • Définitions : • Classe vraie d’un objet : c’est la classe qui a servi à l’instanciation de l’objetex : Dans l’instruction new Pioche ( ), la référence construite porte sur un objet Pioche qui est la classe vraie de l’objet instancié. • Classe apparente d’un objet : c’est toute classe qui, n’étant pas la classe vraie, est l’une des classes appartenant au chemin de dérivation de l’objet. Ici, l’objet sec1, qui a pour classe vraie Secrétaire, peut prendre pour classes apparentes : Employé ou Object Elles correspondent à avoir une vision restreinte, par rapport à ce que l’objet est en réalité. Cela est induit par la relation d’héritage elle-même carun Secrétaire « est une sorte » d’Employéou encore « une sorte » d’Object. Il devient alors possible et naturel de s’intéresser à ce que l’objet est au travers d’une qualité moindre que sa véritable qualité. Cours JAVA / Y.Laborde
Java : un langage Orienté Objet Pour un objet vu au travers d’une classe apparente : • Conséquences : • l’objet est amputé de toutes les propriétés définies dans les niveaux supérieurs à sa classe apparente • seules les propriétés définies au niveau de sa classe apparente restent accessibles • l’objet conserve sa vraie nature mais celle-ci n’est temporairement plus visible • Intérêt et nécessité : • Ex: Si l’on désire mettre tout le personnel d’une entreprise dans un Vector pour pouvoir effectuer des traitements communs à tous (comme établir une liste du personnel relevant de tel ou tel département ou établir l’ensemble des feuilles de paye du personnel), • lorsqu’on récupèrera un par un les éléments du vecteur, ceux-ci seront tantôt des directeurs, tantôt des secrétaires et tantôt des commerciaux ! Mais alors comment savoir ce que tel ou tel élément récupéré sera en réalité ? • Tout au plus pourrons-nous être certains que ce seront tous des employés.D’où l’intérêt de notre classe Employé. • Mais pour pouvoir effectuer nos traitements communs à toute sorte de personnel, il apparaît aussi la nécessité que la classe Employé donne accès à des fonctionnalités suffisantes. Cours JAVA / Y.Laborde
Java : un langage Orienté Objet LES CONCEPTS de L’ORIENTE OBJET : • L’héritage ou la dérivation • introduction au concept d’héritage • discussion : « faut-il hériter ou encapsuler ? » • classes vraies et classes apparentes • le masquage de méthodes • discussion à propos du masquage Cours JAVA / Y.Laborde
Exemple : class Object class Couleur public String toString ( ) public String toString ( ) class Employé class Point public String toString ( ) class PointCouleur class Directeur class Secrétaire class Commercial public String toString ( ) public String toString ( ) pc c s p d Java : un langage Orienté Objet Le masquage de méthodes Définition : • Le masquage : une méthode en masque une autre lorsqu’elle est redéfinie avec la même signature dans une classe dérivée.ex : la méthode public String toString ( ) peut être masquée dans toute classe car elle est définie au niveau de la classe Object. Couleur c = new Couleur (0,0,255); Point p = new Point (1,2); PointCouleur pc = new PointCouleur (p,c); Directeur d = new Directeur ("Dupont",…); Secrétaire s = new Secrétaire ("Dubois",…); Méthode non masquée : p.toString () => "Point:"+<OID du point> Méthodes masquées dans la classe vraie : c.toString () => "(R=0,V=0,B=255)" pc.toString () =>"Point:"+<OID du point>+"(R=0,V=0,B=255)" s.toString () => "Secrétaire[Employé:Dubois]" Méthode masquée héritée : d.toString () => "Employé:Dupont" Cours JAVA / Y.Laborde
Java : un langage Orienté Objet Exercice : • Implémentation des versions masquées de String toString () :Cette méthode doit fournir une représentation textuelle (sous forme d’un objet String) de l’état courant de l’objet. Les classes Couleur et Employé forment simplement leur String sur la base de leur état. public class Couleur { protected byte r, g, b; // l’état public String toString ( ){ // masquage return "(R=" + this.r + "V=" + this.v + "B=" + this.b + ")"; } …} public class PointCouleur extends Point { // l’état et les méthodes hérités protected Couleur c; // l’état complété public String toString ( ){ // masquage return super.toString ( ) + this.c.toString ( ) ; } …} public class Employé { protected String nom ; // l’état public String toString ( ){ // masquage return "Employé:" + this.nom ; } …} public class Secrétaire extends Employé { // l’état et les méthodes hérités public String toString ( ) { // masquage return "Secrétaire[" + super.toString ( ) + "]" ; } …} Les deux autres classes font en partie de même mais complètent leur représentation par la partie héritée.Pour cela, elles « font confiance » au comportement hérité et réfèrent à la super-méthodetoString().Dans notre exemple, puisque la classe Point n’a pas masqué ce comportement, c’est celui de Object qui est invoqué. Cours JAVA / Y.Laborde
Java : un langage Orienté Objet Discussion : « à propos du masquage » Le masquage est une situation normale en Orienté Objet car tout au long des dérivations successives la spécialisation fait apparaître des comportements de plus en plus affinés. Il faudra donc bien parfois compléter les comportements hérités pour tenir compte de la nouvelle spécificité des objets. MAIS cela de doit pas être fait n’importe comment ! Et le masquage doit être réservé à quelques situations bien définies. En effet, lorsque l’on en arrive à masquer une méthode sans que cela ne fasse intervenir une quelconque spécificité de la classe dérivée, cela signifie : • soit que le choix de l’héritage doit être remis en cause, • soit, plus grave, qu’il y a une erreur de conception dans plusieurs classes du chemin de dérivation Par rapport à cela, il est important de connaître les situations normales de masquage. Elles sont présentées au nombre de trois principales (d’autres cas plus subtils pouvant se présenter, il importera de les reconnaître et d’y réfléchir plus spécifiquement). Cours JAVA / Y.Laborde
Java : un langage Orienté Objet Trois situations normales de masquage Cas 1 : Nécessité de rejeter en totalité le comportement hérité pour exprimer la nouvelle spécificité de l’objet. C’est un cas assez fréquent qui ne doit se présenter que lorsque le comportement hérité a été volontairement exprimé de manière générique. Ex 1: la méthode String toString() de Object est souvent à rejeter en totalité Ex 2: une méthode double calcSalaire() au niveau Employé (qui ne sachant pas calculer un salaire sans savoir si l’objet est un Directeur ou autre retournerait la valeur 0.0) serait à rejeter en totalité Cas 2 : Nécessité de compléter le comportement hérité pour exprimer la nouvelle spécificité de l’objet. C’est un cas très fréquent qui se présente lorsque le comportement dérivé doit compléter le traitement hérité. Il donne souvent lieu à l’usage de la variable super pour invoquer le comportement hérité. Ex: la méthode String toString() de PointCouleur qui complète celle de Point en y ajoutant la couleur. Cas 3 : Nécessité d’initier un comportement hérité «vide»pour obliger les dérivations futures à exprimer la nouvelle spécificité de l’objet (et ainsi pouvoir en bénéficier au niveau de la classe apparente de base). Cela est généralement prévu pour initier une liaison retardée ou polymorphisme (vu plus loin). C’est aussi la notion de classes abstraites (vue ci-après). Cours JAVA / Y.Laborde
Java : un langage Orienté Objet LES CONCEPTS de L’ORIENTE OBJET : • L’héritage ou la dérivation • introduction au concept d’héritage • discussion : « faut-il hériter ou encapsuler ? » • classes vraies et classes apparentes • le masquage de méthodes • discussion à propos du masquage • les classes abstraites Cours JAVA / Y.Laborde
Java : un langage Orienté Objet LES CONCEPTS de L’ORIENTE OBJET : • L’héritage ou la dérivation • introduction au concept d’héritage • discussion : « faut-il hériter ou encapsuler ? » • classes vraies et classes apparentes • le masquage de méthodes • discussion à propos du masquage • les classes abstraites • la liaison retardée ou polymorphisme Cours JAVA / Y.Laborde
Java : un langage Orienté Objet LES CONCEPTS de L’ORIENTE OBJET : • L’héritage ou la dérivation • introduction au concept d’héritage • discussion : « faut-il hériter ou encapsuler ? » • classes vraies et classes apparentes • le masquage de méthodes • discussion à propos du masquage • les classes abstraites • la liaison retardée ou polymorphisme • Les interfaces Java • introduction au concept d’interface Cours JAVA / Y.Laborde