GÉNÉRICITÉ
PROGRAMMATION GÉNÉRIQUE
• La généricité a été introduite en Java dans le Jdk 5.0, elle est
utile pour écrire du code réutilisable
• Elle permet de créer des classes, des interfaces et des méthodes
qui peuvent travailler avec différents types de données
• Exemple : La classe ArrayList<E> est une classe générique
(paramétrée), elle possède un type paramètre, noté E et placé
entre <>, qui peut être remplacé par n’importe quel type
référence, e.g. ArrayList<String>
PREMIER EXEMPLE
DÉFINITION D’UNE CLASSE GÉNÉRIQUE
DÉFINITION D’UNE CLASSE GÉNÉRIQUE (SUITE)
UTILISATION D’UNE CLASSE GÉNÉRIQUE
UTILISATION D’UNE CLASSE GÉNÉRIQUE (SUITE)
• Scénario d’exécution :
TYPE PARAMÈTRE
• Par convention, le type paramètre commence par une lettre majuscule.
• Le type concret qui correspond à un type paramètre doit toujours être un
type référence (pas un type primitif tel que int, double, char …)
• Le type paramètre peut être utilisé comme n’importe quel autre type dans
la définition de la classe (e.g., type de paramètre d’une méthode, type de
retour d’une méthode).
• LIMITATION : le type paramètre ne peut pas être utilisé comme un
constructeur pour instancier un objet :
T obj = new T( ) ;
T [ ] tab=new T[10];
Erreur du compilateur : Type parameter ‘T’ cannot be instanciated directly
CONSTRUCTEURS DE CLASSES GÉNÉRIQUES
• Le type paramètre <T> n’apparait pas dans l’entête de la définition des constructeurs :
public Pair(T firstItem, T secondItem) : signature correcte
public Pair<T>(T firstItem, T secondItem) : signature incorrecte
• Cependant, lorsqu’une classe générique est instanciée, les parenthèses angulaires <> sont
utilisées:
Pair<String> pair = new Pair<String>("Happy", "Day");
Ou bien : Pair<String> pair = new Pair<>("Happy", "Day");
• Dans le dernier exemple, le type argument (omis entre <>) est inféré par le compilateur à
partir du contexte
UTILISATION DES CLASSES GÉNÉRIQUES ET AUTO-
BOXING
DÉFINITION D’UNE CLASSE GÉNÉRIQUE AVEC
PLUSIEURS TYPES PARAMÈTRES
DÉFINITION D’UNE CLASSE GÉNÉRIQUE AVEC
PLUSIEURS TYPES PARAMÈTRES
UTILISATION D’UNE CLASSE GÉNÉRIQUE AVEC
PLUSIEURS TYPES PARAMÈTRES
LIMITATION DES TYPES PARAMÈTRES
• Des fois il est souhaitable de limiter les types arguments destinés à remplacer un type paramètre T.
Syntaxe Explication
class RClass<T extends Integer> Seules les classes qui dérivent de la classe Integer peuvent être utilisées
comme type argument
class Rclass<T extends Comparable<T>> Seules les classes qui implémentent l’interface Comparable<T> peuvent
remplacer le type T
L’interface Comparable<T> contient la déclaration de méthode suivante :
int compareTo(T o)
class Rclass <T extends C1 & I1 & I2> Le type argument doit étendre la classe C1 et implémenter les interfaces
I1 et I2 (la classe doit être placée en premier)
• Remarque : le mot clé “extends” est utilisé dans son sens général qui peut signifier “extends” ou
“implements”
• N’importe quelle tentative de remplacer le type T par une classe qui ne respecte par les constraintes de
limitation engendrera une erreur à la compilation
INTERFACE COMPARABLE
• L'interface Comparable<T> fait partie du package java.lang, elle utilisée pour définir un ordre
naturel entre les instances d'une classe.
• Cette interface contient une seule méthode, compareTo dont la signature est la suivante :
public interface Comparable<T> {
int compareTo(T o);
}
• p1.compareTo(p2) renvoie :
• une valeur positive si l’objet courant p1 est supérieur à l’objet paramètre p2
• une valeur négative si l’objet courant p1 est inférieur à l’objet paramètre p2
• 0 si les deux objets sont considérés égaux
LIMITATION DU TYPE PARAMÈTRE : EXEMPLE
MÉTHODES GÉNÉRIQUES
• Une méthode générique peut être définie avec ses propres types paramètres, qui sont
locaux à la méthode et non à la classe
Lorsqu’une méthode générique est invoquée, son nom est préfixé
par le type argument mis entre <>
JOKERS
• L'utilisation de jokers (wildcards) en Java offre une flexibilité supplémentaire
• Joker non borné : ? représente n’importe quel type référence
public static void afficherPair(Pair<?> p){
System.out.println("("+p.getFirst()+" , "+p.getSecond()+")");}
• Joker borné :
• ? extends T : une sous-classe de T ou T lui même
• ? super T : une super-classe de T ou T lui même
public static double sommePair(Pair<? extends Number> p){
Number n1=p.getFirst();
Number n2=p.getSecond();
double n=n1.doubleValue()+n2.doubleValue();
return n;}
Scénarios d’exécution :
System.out.println(sommePair(new Pair<Integer>(3, 5)));
System.out.println(sommePair(new Pair<Double>(3.14, 2.16)));
CLASSES GÉNÉRIQUES ET HÉRITAGE
• Une classe générique peut être définie comme une sous-classe d’une classe ordinaire
ou d’une autre classe générique
• Comme avec une classe ordinaire, un objet instance d’une sous classe est aussi
instance de la superclasse
• ATTENTION : Etant données deux classes A et B, telles que A est une classe dérivée de
B, et une classe générique G<T>, il n’y’a aucune relation entre G<A> et G<B>
CLASSES GÉNÉRIQUES ET HÉRITAGE : EXEMPLE
QUIZ 4
• Ecrire une méthode générique tableauxEgaux qui prend en entrées deux tableaux du même type
générique T et vérifie s’ils contiennent les mêmes éléments dans le bon ordre :
public static <T>boolean tableauxEgaux(T[ ] t1, T[ ] t2)
Scénario d’exécution :
boolean b=tableauEgaux(new Integer[]{1, 2, 3}, new Integer[]{1, 2, 3}); //true
• Ecrire une méthode générique filtrerPlusGrand qui prend en entrée un tableau tab de type générique
T (qui implémente l’interface Comparable<T>) ainsi qu’un objet o de type T et qui renvoie un
nouveau tableau composé des éléments de tab qui sont plus grands que o.
public static <T extends Comparable<T>> Object[ ] filtrerPlusGrand(T[] tab, T o)