"Salut ! Je vais continuer la leçon d'Ellie sur les génériques. Prêt à écouter ?"

"Oui."

"Alors commençons."

"La première chose que vous devez savoir est que les méthodes d'une classe peuvent également avoir leurs propres paramètres de type."

"Je sais."

"Non, je parle spécifiquement de leurs propres paramètres de type : "

Exemple
class Calculator
{
  T add(T a, T b); // Add
  T sub(T a, T b); // Subtract
  T mul(T a, T b); // Multiply
  T div(T a, T b); // Divide
}

"Ces paramètres de type se rapportent spécifiquement aux méthodes. La classe n'a pas de paramètres. Vous pouvez même déclarer ces méthodes statiques et les appeler sans objet."

"Je vois. Le but des paramètres de type dans les méthodes est le même que pour les classes ?"

"Oui. Mais il y a quelque chose de nouveau."

"Comme vous le savez déjà, vous pouvez utiliser un caractère générique dans la déclaration de type. Imaginez alors la situation suivante :"

Exemple 1
public void doSomething(List<? extends MyClass> list)
{
 for(MyClass object : list)
 {
  System.out.println(object.getState()); // Everything works well here.
 }
}

"Mais que se passe-t-il si nous voulons ajouter un nouvel élément à la collection :"

Exemple 2
public void doSomething(List<? extends MyClass> list)
{
 list.add(new MyClass()); // Error!
}

"Le problème est que dans le cas général, la méthode doSomething peut recevoir une List dont les éléments ne sont pas des objets MyClass, mais plutôt des objets de n'importe quelle sous-classe de MyClass. Mais vous ne pouvez pas ajouter d'objets MyClass à une telle liste !"

« Ah. Alors, qu'est-ce qu'on peut faire à ce sujet ?

"Rien. Dans cette situation, vous ne pouvez rien faire. Mais cela a donné matière à réflexion aux créateurs de Java. Et ils ont trouvé un nouveau mot-clé : super ."

"La syntaxe est presque la même :"

List<? super MyClass> list

Mais il y a une distinction importante entre les extensions et les super.

"«? étend T» signifie que la classe doit être un descendant de T."

""? super T" signifie que la classe doit être un ancêtre de T."

"Holy moly. Alors, où est-ce que cela est utilisé?"

""? super T" est utilisé lorsqu'une méthode consiste à ajouter à une collection d'objets T. Dans ce cas, il peut s'agir d'une collection d'objets T ou de tout ancêtre de T."

"Ah. L'objet AT peut être affecté à une variable de référence dont le type est l'un des ancêtres de T"

"Honnêtement, cette approche n'est pas utilisée très souvent. De plus, elle a un défaut. Par exemple :"

Exemples
public void doSomething(List<? super MyClass> list)
{
 for(MyClass object : list) // Error!
 {
  System.out.println(object.getState());
 }
}
public void doSomething(List<? super MyClass> list)
{
 list.add(new MyClass()); // Everything works well here.
}

"Maintenant, le premier exemple ne fonctionne pas."

"Puisque list pourrait même être une List<Object> (Object est la superclasse la plus élevée de MyClass), nous écrivons essentiellement le code invalide suivant :"

Exemple 1
List<Object> list; 

for(MyClass object : list) // Error!
{ 
 System.out.println(object.getState()); 
}

"Je vois. Merci pour la leçon intéressante."

"Je t'en prie."