Les classes paramétrées Daniel Tschirhart : Programmation Java V1.34 Daniel Tschirhart : Programmation Java V1.34 Les classes paramétrées Soit une pile d'é d'éléments dé définie par une classe Pile. public class Pile { private Object[] objects; ... public Pile() { } // Ajouter un élément dans la Pile public void empiler(Object object) { ... } // Obtenir et retirer l'objet situé au sommet Pile public Object depiler() { ... } } 2 Daniel Tschirhart : Programmation Java V1.34 Les classes paramétrées (2) L'instanciation d'un objet p de la classe Pile s'écrit Pile p = new Pile (); Comme la pile peut contenir n'importe que type (la classe Object est la classe parente de toutes les classes) On peut écrire : p.empiler("Dupond"); p.empiler(new Integer(5.0)); p.empiler(new Pile()); p.empiler(new Complex()); p.empiler(5); // erreur 5 n'est pas un objet 3 Daniel Tschirhart : Programmation Java V1.34 Les classes paramétrées (2) Lorsque on effectue un dépilement, le compilateur Java ne peut pas connaitre le type réel à dépiler, il a besoin du programmeur pour lui indiquer quel type de donnée dépiler. Cette opération appelée transtypage est très risquée, car si le type ne correspond pas, c'est le crash assuré. String s = (String) p.depiler(); // OK si la pile contient un String int v = ((Integer) p.depiler()).intValue(); //OK si la pile contient un Integer 4 Daniel Tschirhart : Programmation Java V1.34 Définition d'une classe paramétrée (générique) public class Pile<T> { private Object[] objects; // et non private T[] objects; // un seul fichier Pile.class quel que soit le type public Pile() { ... } public void push(T object) { ... } public T pop() { ... } } 5 Daniel Tschirhart : Programmation Java V1.34 Utilisation des classes paramétrées (2) La généricité permet de paramétrer les classe avec des types, c'est-à-dire que le compilateur connait le type réel des objets utilisés. Pour la classe Pile on écrit : Pile<Complex> p1 = new Pile<Complex>(); // Pile de Complex p.push(new Complex()); // OK p.push(new Double(5.0)); // erreur de compilation p.push(5); // erreur de compilation ATTENTION : le paramétrage ne concerne que les objets et non les primitifs Pile<int> p1 = new Pile<int>(); Pile<Integer> p2 = new Pile<Integer>(); // interdit // correct 6 Daniel Tschirhart : Programmation Java V1.34 Boxing et unboxing Une opération de boxing est une opération permettant de transformer un primitif (type valeur) en objet grâce à sa classe enveloppe. Une opération de unboxing est une opération permettant de transformer un objet primitif encapsulé dans sa classe enveloppe en type valeur. Avec la définition : Pile p = new Pile(); On doit écrire : p.push(new Integer(5)); // boxing int j = ((Integer)p.depiler()).intValue();// unboxing 7 Daniel Tschirhart : Programmation Java V1.34 Boxing et unboxing automatique à parir de Java 5 Avec la définition : Pile<Integer> p= new Pile<Integer>(); On peut écrire : p.push(5); // boxing automatique est traduit en : p.push(new Integer(5)); De même int val = p.pop(); // unboxing automatique est traduit en : int val = ((Integer)p.depiler()).intValue(); 8