Cours JAVA :
Le polymorphisme en Java.
Version 3.05
Julien Sopena1
Équipe REGAL - INRIA Rocquencourt
LIP6 - Université Pierre et Marie Curie
Licence professionnelle DANT - 2013/2014
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 1 / 121
Grandes lignes du cours
L’héritage
Principes de l’héritage
Syntaxe de l’héritage en Java
Héritage et visibilité
Héritage et construction
La redéfinition
La covariance
Interdire l’héritage
Polymorphisme et héritage
Principes du polymorphisme
Protocoles et polymorphisme
Les protocoles standards
Downcasting : la fin du
polymorphisme.
Le polymorphisme impose
des limites à l’héritage
Redéfinition de méthode de
classe
Classes et méthodes
abstraites
Principes des classes
abstraites
Exemple de classe abstraite
Interfaces
Préambule et définition
Déclaration et
implémentation
Polymorphisme d’interface
Classe ou interface ?
Composition d’interfaces
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 2 / 121
Outline
L’héritage
Principes de l’héritage
Syntaxe de l’héritage en Java
Héritage et visibilité
Héritage et construction
La redéfinition
La covariance
Interdire l’héritage
Polymorphisme et héritage
Classes et méthodes abstraites
Interfaces
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 3 / 121
Outline
L’héritage
Principes de l’héritage
Syntaxe de l’héritage en Java
Héritage et visibilité
Héritage et construction
La redéfinition
La covariance
Interdire l’héritage
Polymorphisme et héritage
Classes et méthodes abstraites
Interfaces
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 4 / 121
Rappel – principes de la POO
1. Encapsulation
IRapprochement des données (attributs) et traitements
(méthodes)
IProtection de l’information (private et public)
2. Agrégation (et composition)
IClasse A"A UN" Classe B
3. Utilisation
IClasse A"UTILISE" Classe B
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 5 / 121
Un nouveau principe POO : Héritage
Définition
Le terme héritage désigne le principe selon lequel une classe peut
hériter des caractéristiques (attributs et méthodes) d’autres classes.
Soient deux classes A et B
IRelation d’héritage : Classe B"EST UN" Classe A
IA est la super-classe ou classe mère de B
IB est la sous-classe ou classe fille de A
IExercice : Héritage, Agrégation ou Utilisation ?
ICercle et Ellipse ?
ISalle de bains et Baignoire ?
IPiano et Joueur de piano ?
IEntier et Réel ?
IPersonne, Enseignant et Étudiant ?
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 6 / 121
Motivation pour un nouveau type de relation
entre classes
Une classe décrit les services (comportements et données) d’un
ensemble d’individus
Exemple : la classe Animal (animation graphique)
Animal
+getNom(): String
+manger(...): ...
+dormir(...): ...
+reproduire(...): ...
Problèmes pour implémenter cette spécification :
IElle est trop générale (exemple : manger( ) est très différent
suivant les animaux)
IIl manque les services spécifiques à certaines catégories
d’animaux (exemple : voler( ), nager( ), ...)
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 7 / 121
Les mauvaises solutions
1. Faire que la classe Animal puisse vraiment représenter tous les
animaux
Iaccroître l’interface publique (tous les services possibles de
tous les animaux)
Iajouter des attributs booléens pour les catégories (isOiseau,
isPoisson, ...) ou un attribut qui indique la catégorie
Itester les attributs pour savoir si on peut répondre à un
message
IExemple : Animal unChat = new Animal ("chat",...); (avec un
attribut genreAnimal de type String dans la classe Animal)
Icode très complexe et non maintenable
2. Faire autant de classes qu’il existe d’espèces animales
Ibeaucoup de services vont être très similaires entre les classes
Ibeaucoup de factorisations perdues
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 8 / 121
A
...
B
...
A
...
B
...
Classification hiérarchisée
Animal
Vertébré Invertébré
Mammifère Poisson Reptile
Homme Chat
ILes sous-classes (spécialisations) de la classe Mammifère sont
les classes Homme et Chat
ILes ascendants (généralisations) de la classe Mammifère sont
les classes Vertébré et Animal
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 9 / 121
Héritage
IUne sous-classe hérite des services (comportements et
données) de ses ascendants
IPour factoriser au mieux la programmation, il suffit de placer
les services à la bonne place dans la relation d’héritage
Animal
getNom()
setNom()
Vertébré
remuerVertèbres() Invertébré
Mammifère
allaiter() Poisson nager()
Homme
écrire() Chat
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 10 / 121
Hiérarchie en Java
IUne classe hérite toujours d’une seule et unique classe
(héritage simple versus héritage multiple)
ICette classe est dite super-classe de la sous-classe
IPar défaut, toute classe hérite de la classe Object qui est la
racine unique de l’arbre d’héritage
Object
Animal Question ...
Vertébré Invertébré
Mammifère Poisson Reptile
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 11 / 121
Outline
L’héritage
Principes de l’héritage
Syntaxe de l’héritage en Java
Héritage et visibilité
Héritage et construction
La redéfinition
La covariance
Interdire l’héritage
Polymorphisme et héritage
Classes et méthodes abstraites
Interfaces
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 12 / 121
Syntaxe
Pour indiquer qu’une classe hérite d’une autre classe, on utilise le
mot-clé extends.
public clas s Appartement extends Logement
Important
La classe Appartement ainsi définie possède toutes les caractéris-
tiques de la classe Logement (i.e., ses éléments privés et publics).
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 13 / 121
Spécialisation
public c lass Logement {
f i n a l public double surface ;
public double prix ;
public S tr i n g p r o p r i e t a i r e ;
p r i v a t e bo ole an vendu ;
}
public clas s Appartement extends Logement {
f i n a l public i n t e t a g e ;
p r i v a t e bo ole an cave ;
}
Les attributs de la classe Appartement sont : surface,prix,
proprietaire,vendu,etage et cave.
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 14 / 121
Implémentation en Java
public c l ass Homme extends Mammifère {
// a t t r i b u t s pr op re s aux hommes uniquemen t
p r i v a t e bo ole an d r o i t i e r ;
. . .
public void é c r i r e ( ) {
i f d r o i t i e r { . . . } else {...}
}
}
Homme unHomme = new Homme ( . . . ) ;
// a p p e l d ’ un s e r v i c e p r o p r e au x hommes
unHomme . é c r i r e ( ) ;
// a pp el d ’ un s e r v i c e commun aux v e r t é b r é s ( h é r i t é )
unHomme . r e m u e r V e r t è b r e s ( ) ;
// a pp e l d un s e r v i c e commun aux animaux ( h é r i t é )
unHomme . setNom ( "Adam" ) ;
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 15 / 121
Héritage de comportements
Durant l’exécution, l’instruction :
unHomme . setNom ( "Adam" ) ;
provoque :
ILa recherche de setNom() dans la classe Homme
IPuisqu’elle n’existe pas, la recherche se poursuit en remontant
l’arbre d’héritage jusqu’à trouver Animal.setNom()
IAnimal.setNom() est exécutée (dans le contexte de unHomme)
Si la méthode Animal.setNom() n’était pas définie, une erreur
serait détectée lorsque la classe Object serait atteinte
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 16 / 121
À retenir : la classe Object
Important
En Java, toutes les classes héritent de la classe Object.
La déclaration
public c l ass A { . . . }
doit donc être comprise comme
public c l ass Aextends Ob j e ct { . . . }
même si on ne l’écrit pas ainsi.
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 17 / 121
À retenir : le mot-clé super
Á retenir
Java fournit la référence super qui désigne pour chaque classe,
sa classe mère.
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 18 / 121
Héritage d’attributs
public clas s Anima l {
// a t t r i b u t s pr op re s à t o us l e s anim aux
p r i v a t e S t r i n g nom ; . . .
public S t r i n g getNom ( ) { return nom ; }
public void setNom ( S t r i n g n ) { nom = n ; }
. . .
}
public cla ss Vertébré extends Animal {
// a t t r i b u t s p r o p r e s au x V e r t é b r é s
p r i v a t e i n t nbVertèbres ; ...
public void setNbVertèbres( int n ) {
nbVertèbres = n;
}
public void r e m u e r V e r t è b r e s ( ) {
System . ou t . p r i n t l n ( this.getNom() +" re mue "
+ nbVertèbres + "vertèbres") ;
}
}
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 19 / 121
Héritage d’attributs – suite
public c l ass Homme extends Mammifère {
// a t t r i b u t s pr op re s aux hommes u n i q u e m ent
p r i v a t e bo ole an d r o i t i e r ;
. . .
public Homme ( S t r i n g unNom , boolean d r o i t i e r ) {
this.setNbVertebres(50) ;
this.setNom(unNom) ;
t h i s . d r o i t i e r = d r o i t i e r ;
}
. . .
}
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 20 / 121
Héritage d’attributs – fin
Homme uneFemme = new Homme( "Ève " ,t r ue ) ;
Ève
true
uneFemme
50
true
uneFemme . r e m u e r V e r t è b r e s ( ) ;
System . ou t . p r i n t l n ( uneFemme . getNom ( ) ) ;
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 21 / 121
Outline
L’héritage
Principes de l’héritage
Syntaxe de l’héritage en Java
Héritage et visibilité
Héritage et construction
La redéfinition
La covariance
Interdire l’héritage
Polymorphisme et héritage
Classes et méthodes abstraites
Interfaces
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 22 / 121
Héritage et encapsulation
ILes membres (attributs et méthodes) déclarés privés dans une
classe ne sont pas visibles dans une sous-classe
IEn d’autres termes, l’héritage n’implique pas la visibilité
public c l ass Homme extends Mammifère {
// a t t r i b u t s pr op re s aux hommes u n i q u e m ent
p r i v a t e bo ole an d r o i t i e r ;
. . .
public Homme ( S t r i n g unNom , boolean d r o i t i e r ) {
t h i s . setNbVertebres (50);
nom = unNom ;// e r r e u r
t h i s . d r o i t i e r = d r o i t i e r ;
}
. . .
}
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 23 / 121
Visibilité
Le modificateur qui précède chaque méthode (et attribut)
détermine sa visibilité :
private défaut protected public
la classe elle-même OUI OUI OUI OUI
une sous-classe, paquetage =NON OUI OUI OUI
pas une sous-classe, paquetage =NON OUI OUI OUI
une sous-classe, paquetage 6=NON NON OUI OUI
pas une sous-classe, paquetage 6=NON NON NON OUI
Rappel
Les attributs doivent toujours être déclarés private
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 24 / 121
Outline
L’héritage
Principes de l’héritage
Syntaxe de l’héritage en Java
Héritage et visibilité
Héritage et construction
La redéfinition
La covariance
Interdire l’héritage
Polymorphisme et héritage
Classes et méthodes abstraites
Interfaces
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 25 / 121
Instantiation des attributs hérités
public c l ass Homme extends Mammifère {
// a t t r i b u t s pr op re s aux hommes u n i q u e m ent
p r i v a t e boo lea n d r o i t i e r ;
. . .
public Homme ( S t r i n g unNom , boolean d r o i t i e r ) {
this.setNbVertèbres(50) ;
this.setNom(unNom) ;
t h i s . d r o i t i e r = d r o i t i e r ;
}
. . .
}
Problèmes
IObligation d’introduire des modificateurs telles que
Vertébré.setNbVertèbres()
IRedondance – la super-classe Mammifère doit avoir un
constructeur
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 26 / 121
Héritage et construction – Correction
Pour initialiser les attributs hérités, le constructeur d’une classe
peut invoquer un des constructeurs de la classe mère à l’aide du
mot-clé super.
public c l ass Homme extends Mammifère {
p ri va te s t a t i c f i n a l i n t NB_VERTEBRES = 5 0 ;
p r i v a t e bo ole an d r o i t i e r ;
public Homme ( S t r i n g unNom , boolean droitier ,
int nbVertèbres) {
// s u pe r d o i t ê t r e l a p re mi è r e i n s t r u c t i o n
super ( unNom , n b V e r t è b r e s ) ;
t h i s . d r o i t i e r = d r o i t i e r ;
}
public Homme ( S t r i n g unNom , boolean d r o i t i e r ) {
t h i s (unNom , d r o i t i e r , NB_VERTEBRES ) ;
}
}
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 27 / 121
Règles d’utilisation d’un constructeur de la classe
mère.
Règles
1. L’appel d’un constructeur de la classe mère doit être la
première instruction du constructeur de la classe fille.
2. Il n’est pas possible d’utiliser à la fois un autre constructeur
de la classe et un constructeur de sa classe mère dans la
définition d’un de ses constructeurs.
public c l ass A {
public A( int x ) {
super ();
t h i s ();
}
}
INTERDIT
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 28 / 121
Constructeur implicite
Si aucun constructeur de la classe ou de la super-classe n’est
invoqué explicitement, le compilateur ajoute un appel au
constructeur sans argument de la super-classe
public c l ass Bextends A {
public B( int x ) {
// a p p e l s u p e r ( ) i m p l i c i t e
t h i s . x = x ;
. . .
}
}
Attention : Dans ce cas, le constructeur sans argument doit être
défini dans la super-classe
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 29 / 121
Constructeur implicite : exemple
public c l ass A {
public A ( ) { System . o u t . p r i n t l n ( "A" ) ; } }
public cla ss Bextends A {
public B ( ) { System . o u t . p r i n t l n ( "B" ) ; } }
Le ligne de code suivante :
B c = new B ( ) ;
produira l’affichage suivant :
java MonProg
A
B
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 30 / 121
Constructeur implicite : erreur fréquente
Etape 1 :
Jusqu’ici tout va bien.
public c l ass A {
public i n t x ;
}
public cla ss Bextends A {
public i n t y ;
public B ( int x , int y ) {
t h i s . x = x ;
t h i s . y = y ;
}
}
Etape 2 :
Puis, on ajoute un constructeur.
public c l ass A {
public i n t x ;
public A (int x) {
this.x =x;
}
}
public cla ss Bextends A {
public i n t y ;
public B ( int x , int y ) {
t h i s . x = x ;
t h i s . y = y ;
}
}
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 31 / 121
Constructeur implicite : erreur fréquente
javac B.java
B.java:3: cannot find symbol
symbol : constructor A()
location: class A
public B ( int x , int y ) {
^
1 error
}
public cla ss Bextends A {
public i n t y ;
public B ( int x , int y ) {
super() ; \\ A j out du c o m p i l a t e u r
t h i s . x = x ;
t h i s . y = y ;
}
}
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 32 / 121
Constructeur implicite : Solutions
Solution 1 :
Ajout d’un constructeur vide.
public c l ass A {
public i n t x ;
public A () {}
public A ( int x ) {
t h i s . x = x ;
}
}
public cla ss Bextends A {
public i n t y ;
public B ( int x , int y ) {
t h i s . x = x ;
t h i s . y = y ;
}
}
Solution 2 :
Appel explicite au super(int).
public c l ass A {
public i n t x ;
public A ( int x ) {
t h i s . x = x ;
}
}
public c l ass Bextends A {
public i n t y ;
public B ( int x , int y ) {
super(x);
t h i s . y = y ;
}
}
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 33 / 121
Constructeur d’une classe dérivée
Un constructeur d’une classe dérivée commence toujours :
1. soit par l’appel explicite d’un autre constructeur de la classe.
2. soit par l’appel explicite ou implicite d’un constructeur de la
classe mère.
Corollaire
Comme tout objet dérive (directement ou indirectement) de la
classe Object :Tout constructeur commence par exécuter
le constructeur de l’Object
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 34 / 121
Outline
L’héritage
Principes de l’héritage
Syntaxe de l’héritage en Java
Héritage et visibilité
Héritage et construction
La redéfinition
La covariance
Interdire l’héritage
Polymorphisme et héritage
Classes et méthodes abstraites
Interfaces
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 35 / 121
Définition de la redéfinition.
Définition
On appelle redéfinition (en anglais « overriding ») d’une méthode,
la possibilité de définir le comportement d’une méthode selon le
type d’objet l’invoquant, i.e., de donner une nouvelle
implémentation à une méthode héritée sans changer sa signature.
public c l ass A {
public i n t f (int x) {
. . .
}
}
public c l ass B e xt e nd A {
public i n t f (int x) {
. . .
}
}
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 36 / 121
La signature d’une méthode Java
public c l ass Homme extends Mammifère {
. . .
public void dessiner () {
System . ou t . p r i n t l n ( " G r i b o u i l l i s " ) ;
}
}
public cla ss Leonard extends Homme {
. . .
public void dessiner () {
System . ou t . p r i n t l n ( " Jocond e " ) ;
}
}
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 37 / 121
Overloading vs Overriding
ATTENTION
Il ne faut pas confondre la redéfinition (en anglais « overriding »)
et la surcharge (en anglais « overloading ») qui a été étudiée
dans le cours d’introduction et qui correspond à la possibilité de
définir des comportements différents pour la même méthode selon
les arguments passés en paramètres.
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 38 / 121
Surcharge d’une méthode redéfinie
On peut aussi surcharger une méthode redéfinie.
public c lass Logement {
public void v e n d r e ( S t r i n g a c q u e r e u r ) {
t h i s . p r o p r i e t a i r e = a c q u e r e u r ;
t h i s . vendu = t r ue ;
}
}
public clas s Appartement extends Logement {
public void v e n d r e ( S t r i n g a c q u e r e u r ) {
t h i s (acquereur );
t h i s . c a ve = false :
}
public void v e n d r e ( S t r i n g a c q u e r e u r , boolean c ave ) {
t h i s (acquereur );
t h i s . c a ve = ca v e :
}
}
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 39 / 121
Spécialiser une méthode héritée
La référence super permet de redéfinir une méthode fhéritée en
réutilisant sa définition dans la classe mère. On dit alors qu’on
spécialise la méthode héritée f.
public c l ass A {
public void f ( ) {
. . .
}
}
public c l ass Bextends A {
public void f ( ) {
. . .
super.f()
. . .
}
}
J. Sopena (INRIA/UPMC) Le polymorphisme en Java. 40 / 121
1 / 16 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !