9.1 Classes génériques
Une classe générique est une classe paramétrée par un type générique T, déclaré avec la notation diamant <T> :
public class MaClasseGenerique <T> {}
Le type générique est appelé T par convention, on peut lui assigner la lettre qu’on veut.
Il est possible de paramétrer plusieurs types génériques.
Dans le body, le type générique T est un attribut à définir : protected T t;.
Il est possible d’ajouter d’autres attributs normalement.
Il est possible d’ajouter des méthodes normalement, qui peuvent utiliser l’attribut générique t sans souci.
Lors de la création d’une instance de classe générique, le type générique est remplacé par n’importe quelle classe :
MaClasseGenerique<UneClasseAuChoix> monIstance = new MaClasseGenerique<UneClasseAuChoix>();
Il est optionnel de répéter la classe entre diamants la seconde fois :
MaClasseGenerique<UneClasseAuChoix> monIstance = new MaClasseGenerique<>();
Le type générique ne peut pas être remplacé par un type de base : on utilise les classes wrapper correspondantes (décrites au ??).
Le transtypage fonctionne ici aussi : on peut faire appel aux enfants du type générique T donné à la classe générique, çàd donner en paramètre une classe mère et utiliser des classes enfants.
Il est possible d’ajouter des contraintes sur le type générique, en autorisant uniquement d’assigner des classes qui :
- héritent d'une classe spécifique : `<T extends UneClasse>`
- implémentent un ou plusieurs interface : `<T extends UnInterface & UnAutreInterface>`
- font les deux : `<T extends UneClasse & UnInterface & UnAutreInterface>`
Il faut spécifier la classe mère avant les interfaces.
UML : dans les diagrammes de classe, les classes génériques sont représentées avec un carré en haut à droite de la classe, dont le contour est en pointillés et qui contient la lettre du type générique.