20
1 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

1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

Embed Size (px)

Citation preview

Page 1: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

1

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

Page 2: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

2

Cours JAVA / Y.Laborde

Java : un langage Orienté Objet

L’HERITAGE ou LA DERIVATIONL’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)

des propriétés héritées peuvent être masquées pour être redéfinies en partie (cas où elles ne conviendraient pas totalement)

de nouvelles propriétés peuvent être ajoutées (qui spécialisent la classe qui hérite)

class B extends class A {

nouvelles propriétés }

Classe A A::Prop 1 A::Prop 2 …

Accès direct à toutes les propriétés de A( comme si elles avaient été déclarées dans

B )

Masquage de la propriété 2 :A::Prop 2 => B::prop 2

hérite dela classe A

Page 3: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

3

Cours JAVA / Y.Laborde

Java : l’héritage (ou la dérivation)

LA RELATION D’HERITAGE entre deux classes exprime que :

la classe qui hérite « EST UNE SORTE DE » la classe héritée

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

class Vector C’est la classe de l’API Java (package java.util)qui est un vecteur admettant des éléments de classe Object

Un vecteur de dominos est une sorte de vecteurmais n’admettant que des éléments de classe Domino

(utile pour ne plus avoir à faire de « cast »)

Une main de joueur est une sorte de vecteur de dominos permettant en plus de les classer par marquesUne pioche est une sorte de vecteur de dominos permettant en plus de piocher aléatoirement un domino.Une ligne de jeu est une sorte de vecteur de dominos permettant en plus l’ajout de dominos à droite et à gauche.

Exemples :

class VectDominos

class MainJoueur class Pioche

(depuis Java 5)

class ArrayList<Domino>

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.

class LigneDeJeu

Une main de joueur est une sorte de liste de dominos permettant en plus de les classer par marquesUne pioche est une sorte de liste de dominos permettant en plus de piocher aléatoirement un domino.Une ligne de jeu est une sorte de liste de dominos permettant en plus l’ajout de dominos à droite et à gauche.

Page 4: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

4

Cours JAVA / Y.Laborde

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

Exemple :class Object

class Couleur

class Point

class Domino

class Employé

class PointCouleur class Directeur class Secrétaire

class Commercial

class ArrayList<Domino>

class Main

class LigneDeJeu

class Pioche

Les relations inter-packages peuvent passer par des relations d’héritage

Page 5: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

5

Cours JAVA / Y.Laborde

Java : l’héritage (ou la dérivation)

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)

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)

Page 6: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

6

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 ? »

Page 7: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

7

Cours JAVA / Y.Laborde

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 :

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

void addElement (Domino) Domino elementAt (int) int size ( )

void addDomino (Domino) Domino dominoAt (int) int nombreDominos ( )

Ou pour être plus

proche du concept

de dominos :

Page 8: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

8

Cours JAVA / Y.Laborde

Java : un langage Orienté Objet

Cas1: Implémentation de la classe VectDominos par héritage ou encapsulation d’un Vector :

class VectDominos extends Vector {

void addDomino (Domino d) {

super.addElement (d);

}

Domino dominoAt (int i) {

return (Domino) super.elementAt (i);

}

}

HERITAGE

class VectDominos {

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 ( ); }}

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

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.

Page 9: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

9

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.

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.

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.

Page 10: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

10

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

Page 11: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

11

Cours JAVA / Y.Laborde

Java : un langage Orienté Objet

Classes vraies et classes apparentesDéfinitions : Classe vraie d’un objet : c’est la classe qui a servi à l’instanciation de l’objet

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

Exemple : class Object

class Employé

class Directeur class Secrétaire

class Commercial Objet sec1

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

Page 12: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

12

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.

Page 13: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

13

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

Page 14: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

14

Cours JAVA / Y.Laborde

Java : un langage Orienté Objet

Le masquage de méthodesDé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é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"

Méthode non masquée :

p.toString () => "Point:"+<OID du point>

Exemple :class Object

class Couleur

class Point class Employé

class PointCouleur class Directeur class Secrétaire

class Commercial

public String toString ( )

public String toString ( )

public String toString ( )

public String toString ( )

public String toString ( )

pc

c

sd

p

Page 15: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

15

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.

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 classes Couleur et Employé forment simplement leur String sur la base de leur état.

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éthode toString().Dans notre exemple, puisque la classe Point n’a pas masqué ce comportement, c’est celui de Object qui est invoqué.

Page 16: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

16

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

Page 17: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

17

Cours JAVA / Y.Laborde

Java : un langage Orienté Objet

Cas 1Cas 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é

Trois situations normales de masquage

Cas 2Cas 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 3Cas 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).

Page 18: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

18

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

Page 19: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

19

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

Page 20: 1 Cours JAVA / Y.Laborde Java : un langage Orienté Objet LES CONCEPTS de LORIENTE OBJET : Lhéritage ou la dérivation introduction au concept dhéritage

20

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