La Généricité en Java : Concepts et Applications

Institut Supérieur des Études Technologiques
1/19
100%
Rendu du PDF...
Page 1 sur 19Lecteur de document UniversityLib

La Généricité en Java : Concepts et Applications

Institut Supérieur des Études Technologiques · Advanced Object-Oriented Programming · course

Voir tous les documents en programmation

La généricité

(d’après le cours de Philippe GENOUD )

Cours de Programmation Orientée Objet Avancée

ISET Bizerte CHALOUAH Anissa

Anissa CHALOUAH

1

Généricité : motivation

Supposons que l'on développe du code pour gérer une file d'attente

(FIFO First In First Out) et que l'on veuille utiliser ce code pour

une file d'entiers une file de chaînes de caractères (String) une file d'objets Personne ,,,,,,,,,,,,

Anissa CHALOUAH

2

Généricité : motivation

1ère solution : écrire une classe pour chaque type de valeur que l'on peut mettre dans la file

class ElementInt { private final int value; private ElementInt next; ElementInt(int val) { this.value = val; next = null; } void inserer(ElementInt elt) { this.next = elt; } int getValue() { return value; } ElementInt getNext() { return next; } }

public class FileAttenteInt {

private ElementInt tête = null; private ElementInt queue = null; public void ajouter(int val) {

ElementInt elt = new ElementInt(val); if (estVide()) { tête = queue = elt; } else { queue.inserer(elt); queue = elt; } }

public boolean estVide() { return tête == null;} public int retirer() {

int val = -1; if (!estVide()) { val = tête.getValue(); tête = tête.getNext(); }

return val; }

}

Anissa CHALOUAH

3

Généricité : motivation

class ElementPersonne { private final Personnevalue; private ElementPersonne next; ElementPersonne(Personne val) { this.value = val; next = null; } void inserer(ElementPersonne elt) { this.next = elt; } int getValue() { return value; } ElementPersonne getNext() { return next; } ; }

public class FileAttentePersonne {

private ElementPersonne tête = null; private ElementPersonne queue = null; public void ajouter(Personne val) {

ElementPersonne elt = new ElementPersonne(val if (estVide()) { tête = queue = elt; } else { queue.inserer(elt); queue = elt; } }

public boolean estVide() { return tête == null public int retirer() {

int val = -1; if (!estVide()) { val = tête.getValue(); tête = tête.getNext(); }

return val; }

}

Anissa CHALOUAH

4

Généricité : motivation

1ère solution : écrire une classe pour chaque type de valeur que l'on peut mettre dans la

file

Duplication du code, source d'erreurs à l'écriture et lors de modifications du programme Nécessité de prévoir toutes les combinaisons possibles pour une application

Anissa CHALOUAH

5

Publicité

Généricité : motivation

2ème solution : utiliser un type "universel", Object en Java

class Element {

private final Object value; private Element next; Element(Object val) {

this.value = val; next = null;

} void inserer(Element elt) {

this.next = elt; }

public Object getValue() {

return value; }

public Element getNext() {

return next; }

}

public class FileAttente { private Element tête = null; private Element queue = null; public void ajouter(Object val) { Element elt = new Element(val); if (estVide()) { tête = queue = elt; }

else { queue.inserer(elt); queue = elt; } }

public boolean estVide() { return tête == null;} public Object retirer() {

Object val = null; if (!estVide()) { val = tête.getValue(); tête = tête.getNext(); }

return val; }

toute classe héritant de Object, il est possible d'utiliser FileAttente pour stocker n'importe quel type d'objet

}

Anissa CHALOUAH

6

Généricité : motivation

2ème solution : utiliser un type "universel", Object en Java

FileAttente f1 = new FileAttente(); f1.add(new Personne(...));

FileAttente f2 = new FileAttente(); f2.add(new Voiture(...));

Anissa CHALOUAH

7

Généricité : motivation

FileAttente f1 = new FileAttente(); f1.ajouter(new Personne(...)); ... // on veut récupérer le nom de la personne // en tête de file. String nom = (Personne)(f1.retirer()).getNom();

Transtypage

Object

f1.ajouter("Hello");

String nom = (Personne)(f1.retirer()).getNom();

ClassCastException

obligation pour le programmeur d'effectuer un transtypage lorsqu’il accède aux éléments de la file d'attente

pas de contrôle sur les valeurs rangées dans la file d'attente

 code lourd, moins lisible, plus difficile à maintenir  risques d’erreurs d’exécution.

Anissa CHALOUAH

8

Généricité : motivation

Mais ça, c'était avant…

Publicité

depuis la version 1.5 de java (Tiger), cela n’est qu’un mauvais souvenir grâce à

l’introduction (enfin !) de la généricité dans le langage Java.

Anissa CHALOUAH

9

Généricité : Principe

La généricité (ou polymorphisme paramétrique) permet de faire des abstractions sur

les types .

utiliser des types (Classes ou Interfaces) pour paramétrer une définition de classe ou d'interface

ou de méthode

réutiliser le même code avec des types de données différents.

Présente dans de nombreux langages de programmation avant introduction en Java :

Eiffel, Ada, C++, Haskell, ...

Présente dans le langage de modélisation UML

Anissa CHALOUAH

10

Les classes Element et FileAttente sont paramétrées en fonction d’un type formel T T est utilisé comme type d'une ou plusieurs caractéristiques. Les classes manipulent des

informations de type T. Elles ignorent tout de ces informations.

Anissa CHALOUAH

11

Utilisation d'une classe générique simple

Lors de l’instanciation de FileAttente<T> le type formel T est remplacé par un type

(Classe ou Interface) existant

Le type est passé en argument

FileAttente<Personne> f1 = new FileAttente<Personne> (); f1.add(new Personne(...));

FileAttente<Voiture> f2 = new FileAttente<> (); f2.add(new Voiture(...));

Depuis la version Diamond (java 7), on n'est pas obligé de mentionner les arguments de type dans le constructeur

Anissa CHALOUAH

12

Utilisation d'une classe générique simple

La généricité simplifie la programmation, évite de dupliquer du code et le rend plus robuste

Anissa CHALOUAH

13

Types Génériques Simples

Type générique : Classe ou interface paramétrée par un ou plusieurs types

classe générique à deux paramètres

public class Paire<T1, T2> {

private final T1 first; private final T2 second; public Paire(T1 first, T2 second)

{

this.first = first; this.second = second;

} public T1 getFirst() { return

first; }

Publicité

public T2 getSecond() { return

second; } }

Anissa CHALOUAH

Interface générique

public interface Comparable<T> {

int compareTo(T o);

}

14

Instanciation d'un type générique

Instanciation (invocation) d'un type générique consiste à valuer les paramètres de type Les arguments de type (paramètres effectifs) peuvent être :

des classes(concrètes ou abstraites) Paire<String, Forme> c1 = new Paire<>("Cercle 1",new Cercle(0,0,10));

des interfaces Paire<String, IDessinable> c2 = new Paire<>("Visage 1", new VisageRond());

des types paramétrés Paire<String, Paire<String,Forme>> = new Paire<>("Paire 3",c1);

des paramètres de type

public class FileAttente<E> { private Element<E> tête = null; ...

Anissa CHALOUAH

15

Compilation de code générique

compilation de code générique basée sur le mécanisme d'effacement (erasure)

Anissa CHALOUAH

16

Conséquences de l’effacement du type

à l'exécution, il n'existe qu'une classe (le type brut) partagée par toutes les instanciations du

type générique

mais cela induit un certain nombre de limitations

les membres statiques d'une classe paramétrée sont partagés par toutes les instanciations de celle-ci

Anissa CHALOUAH

17

Généricité : limitations

Les membres statiques d'une classe paramétrée ne peuvent pas utiliser ses paramètres de type au sein d'une classe paramétrée on ne peut pas utiliser les paramètre de type pour instancier un

objet (simple ou tableau)

Anissa CHALOUAH

18

Généricité : limitations

Seul le type brut est connu à l’exécution: au sein d'une classe paramétrée on ne peut pas utiliser les paramètre de type pour instancier un

objet (simple ou tableau)

Anissa CHALOUAH

19