<!-- Slide number: 1 -->
Conception par Objet et Programmation Java
1

Chapitre 5 : Polymorphisme
Equipe Java
2019-2020

Notes:
<!-- Slide number: 2 -->
Plan
2
Introduction
Classe et objet
Encapsulation
Héritage
Polymorphisme
Exceptions
Connexion Base de donnée
Interfaces
Lambda Expression
Collections
Stream
Notes:
<!-- Slide number: 3 -->
Objectifs
3
Redéfinition de méthodes dans les sous-classes : POLYMORPHISME
Sur-classement et substitution.
Le transtypage (conversion de type ou cast en anglais)
Classe et méthode Final
Notes:
<!-- Slide number: 4 -->
Polymorphisme: Définition
4
N’importe quel objet en Java qui peut passer d’une relation « est un » peut être considéré polymorphe.
Le polymorphisme est le fait qu’une même
écriture peut correspondre à différents appels de méthodes
<!-- Slide number: 5 -->
Polymorphisme: Définition
5
Le polymorphisme est le fait de référencer une classe fille avec un référence déclaré de type une classe mère.
Exemple:
Animal
Animal myDog = new Dog();
Référence déclaré en
tant qu’Animal().
Objet crée en
tant que Dog().
Dog
<!-- Slide number: 6 -->
Exemple : Tableau Polymorphique (1/3)
Publicité
6
Avec le polymorphisme : le type de la référence peut être la classe mère de l’objet instancié.
un tableau polymorphique.
Animal
Soit : Animal [ ] animals = new Animal [3];
Déclarer un tableau de type Animal.
Un tableau qui contiendra des objets
de type Animal.
Dog
Cat
Wolf
animals [0] = new Dog();
animals [1] = new Cat();
animals [2] = new Wolf();
On peut affecter les classes « filles » de la classe Animal dans le tableau ( de type Animal).
<!-- Slide number: 7 -->
Exemple : Tableau Polymorphique (2/3)
7

| | | |
| --- | --- | --- |



<!-- Slide number: 8 -->
Exemple : Tableau Polymorphique (3/3)
8


| | | |
| --- | --- | --- |
<!-- Slide number: 9 -->
Exemple : Argument Polymorphique
9



La méthode giveShot() de Vet peut prendre soit un objet Cat ou Dog tant que l’objet passé en paramètre est une classe fille de Animal.
makeNoise() dit être implémenté dans les classes Cat et Dog
<!-- Slide number: 10 -->
Surclassement et Substitution
10
Animal animal;
Dog myDog = new Dog();
animal = myDog;
Animal
public void eat(){
sout(’’je manges’’)
}
public void roam(){
sout(’’je voyages’’)
}
Publicité
Cat
Dog
public void watch(){
sout(’’je gardes’’)
}
Wolf
| myDog.eat() | OK |
| --- | --- |
| myDogl.roam() | OK |
| myDog.watch() | OK |
| animal.eat() | OK |
| --- | --- |
| animal.roam() | OK |
| animal.watch() | KO |
<!-- Slide number: 11 -->
Surclassement et Substitution
11
l’objet Dog crée est « surclassé » il est vu de type Animal référence déclaré (animal).
Les fonctionnalités de Dog sont restreintes à celles de Animal
Le chien ne pourra pas être un chien de garde (il peut pas appelé watch()).
Il faut donc substituer animal par :
((Dog) animal).watch();
| animal.eat() | OK |
| --- | --- |
| animal.roam() | OK |
| ((Dog) animal).watch() | OK |
<!-- Slide number: 12 -->
instanceof
12
Si x est une instance d’une sous-classe B de A
x instanceof A renvoie true
Pour tester si un objet o est de la même classe que l’objet courant, il ne faut donc pas utiliser instanceof mais le code suivant :
if (o != null && o.getClass() == this.getClass())
<!-- Slide number: 13 -->
Le polymorphisme au runtime
13
Mais quel est la méthode qui va s’exécuter ?
Comment se fait l’appel des méthodes à l’exécution
(au runtime)?
<!-- Slide number: 14 -->
Le polymorphisme au runtime
14
Animal
public void eat(){
sout(’’je manges’)
}
public void roam(){
sout(’’je voyages’)
}
Animal animal = new Dog();
aniaml.eat();
Dog
Publicité
public void eat(){
sout(’’Un chien mange’’)
}
public void roam(){
sout(’’Un chien voyage’’)
}
public void watch(){
sout(’’je gardes’)
}
Lorsqu’une méthode d’un objet est accédée au travers d’une référence “surclassée” (animal),
c’est la méthode définie au niveau de la classe réelle (Dog) de l’objet qui est invoquée et exécutée (« Un chien mange »)
<!-- Slide number: 15 -->
Le polymorphisme au runtime
15
le choix du code à exécuter (pour une méthode polymorphe) ne se fait pas statiquement à la compilation mais dynamiquement à l'exécution.
Le polymorphisme qui est fondamental en programmation OO est rendu possible par le fait que les messages sont résolus dynamiquement (message binding).
<!-- Slide number: 16 -->
Quel est la méthode appelée ?
16
Animal
makeNoise()
eat()
sleep()
roam()
Canine
roam()
Wolf
makeNoise()
eat()
Wolf w = new Wolf();
Quand vous appelez une méthode d’un objet référencé, vous appelez au fait la méthode la plus spécifique du type de cet objet.
Le type le plus inférieur gagne !
(inférieur : dans l’arbre d’héritage.)
w.makeNoise();
w.roam();
w.eat();
w.sleep();
La machine virtuelle JVM commence tout d’abord à voir dans la classe Wolf . Si elle ne trouve pas une correspondance de la version de la méthode,
elle commence à grimper l’hiérarchie de l’héritage jusqu’à trouver la bonne méthode.
Notes:
<!-- Slide number: 17 -->
UpCast : classe fille → classe mère
17
Upcast : un objet est considéré comme une instance d’une des classes ancêtres de sa classe réelle
Il est toujours possible de faire un upcast : à cause de la relation est-un de l’héritage, tout objet peut être considéré comme une instance d’une classe ancêtre
Le upcast est souvent implicite
<!-- Slide number: 18 -->
DownCast : classe mère → classe fille
18
Downcast : un objet est considéré comme étant d’une classe fille de sa classe de déclaration
Toujours accepté par le compilateur, mais peut provoquer une erreur à l’exécution si l’objet n’est pas du type de la classe fille
Un downcast doit toujours être explicite
Publicité
<!-- Slide number: 19 -->
Cacher une méthode static
19
On ne redéfinit pas une méthode static, on la cache (comme les variables)
Si la méthode static m de Classe1 est cachée par une méthode m d’une classe fille, la différence est que :
– on peut désigner la méthode cachée de Classe1 en préfixant par le nom de la classe : Classe1.m()
– ou par un cast(x est une instance d'une classe fille de Classe1 : ((Classe1)x)m()
- mais on ne peut pas la désigner en la préfixant par « super. »
<!-- Slide number: 20 -->
Final : classe/méthode
20
Classe final : ne peut avoir de classes filles


Méthode final : ne peut être redéfinie


<!-- Slide number: 21 -->
Equals / Définition
21
La méthode equals() permet de vérifier si l'objet qui lui est fourni en paramètre est égal à l'objet sur laquelle la méthode est invoquée. Sa signature est la suivante : public boolean equals(Object obj)
L'opérateur == vérifie si deux objets sont identiques : il compare que les deux objets possèdent la même référence mémoire et sont donc en fait le même objet.
Deux objets identiques sont égaux mais deux objets égaux ne sont pas forcement identiques.
La méthode equals() vérifie l'égalité de deux objets : son rôle est de vérifier si deux instances sont sémantiquement équivalentes même si ce sont deux instances distinctes.
Chaque classe peut avoir sa propre implémentation de l'égalité mais généralement deux objets sont égaux si tout ou partie de leurs états sont égaux.
21
<!-- Slide number: 22 -->
Equals / Implémentation
22
public class Animal
{
String name;
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) { // if(!(obj instanceof Animal))
return false;
}
final Animal animal = (Animal) obj;
if (this.name != animal.name) {
return false;
}
return true;
}
}