"Hallo! Ik ga verder met Ellie's les over generieke geneesmiddelen. Klaar om te luisteren?"
"Ja."
"Laten we dan beginnen."
"Het eerste dat u moet weten, is dat de methoden van een klasse ook hun eigen typeparameters kunnen hebben."
"Ik weet."
"Nee, ik bedoel specifiek hun eigen typeparameters: "
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
}
"Deze typeparameters hebben specifiek betrekking op de methoden. De klasse heeft geen parameters. Je zou deze methoden zelfs statisch kunnen declareren en ze zonder object kunnen aanroepen."
"Ik begrijp het. Het punt van de typeparameters in methoden is hetzelfde als voor klassen?"
'Ja. Maar er is iets nieuws.'
"Zoals je al weet, kun je een wildcard gebruiken in de typedeclaratie. Stel je dan de volgende situatie voor:"
public void doSomething(List<? extends MyClass> list)
{
for(MyClass object : list)
{
System.out.println(object.getState()); // Everything works well here.
}
}
"Maar wat als we een nieuw item aan de collectie willen toevoegen:"
public void doSomething(List<? extends MyClass> list)
{
list.add(new MyClass()); // Error!
}
"Het probleem is dat in het algemeen de doSomething-methode een lijst kan worden doorgegeven waarvan de elementen geen MyClass-objecten zijn, maar eerder objecten van een subklasse van MyClass. Maar je kunt geen MyClass-objecten aan zo'n lijst toevoegen!"
"Ah. Dus, wat kan daar aan gedaan worden?"
"Niets. In deze situatie kun je niets doen. Maar dit gaf de makers van Java iets om over na te denken. En ze kwamen met een nieuw trefwoord: super ."
"De syntaxis ziet er bijna hetzelfde uit:"
List<? super MyClass> list
Maar er is een belangrijk onderscheid tussen verlengt en super.
"«? extends T» betekent dat de klasse een afstammeling moet zijn van T."
"«? super T» betekent dat de klasse een voorouder moet zijn van T."
"Holy moly. Dus waar wordt dit gebruikt?"
"«? super T" wordt gebruikt wanneer een methode het toevoegen aan een verzameling T-objecten inhoudt. In dit geval kan het een verzameling T-objecten zijn of een voorouder van T."
"Ah. AT-object kan worden toegewezen aan een referentievariabele waarvan het type een van de voorouders van T is"
"Eerlijk gezegd wordt deze aanpak niet vaak gebruikt. Bovendien heeft het een tekortkoming. Bijvoorbeeld:"
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.
}
"Nu werkt het eerste voorbeeld niet."
"Aangezien lijst zelfs een Lijst<Object> zou kunnen zijn (Object is de hoogste superklasse van MyClass), schrijven we in wezen de volgende ongeldige code:"
List<Object> list;
for(MyClass object : list) // Error!
{
System.out.println(object.getState());
}
"Ik snap het. Bedankt voor de interessante les."
"Graag gedaan."
GO TO FULL VERSION