"Nu een nieuw, interessant onderwerp: wildcards."
"In wezen is dit zoiets als een «*» patroon dat overal bij past."
"Maar laten we bij het begin beginnen."
"Stel je voor dat je een Warrior-klasse hebt en een methode die bepaalt welke van de twee krijgers sterker is. Zo zou dit eruit kunnen zien:"
class WarriorManager
{
public static boolean fight(Warrior w1, Warrior w2)
{
return w1.power > w2.power;
}
}
MagicWarrior mag = new MagicWarrior();
ArcherWarrior archer = new ArcherWarrior();
boolean isMagicCooler = WarriorManager.fight(mag, archer);
"MagicWarrior en ArcherWarrior erven allebei Warrior. ."
"Het is een beetje simplistisch, maar voor een voorbeeld is het voldoende."
"OK."
"Stel nu dat je hebt besloten om een vergelijkbare methode te maken voor de situatie waarin meerdere krijgers zich bij de strijd hebben aangesloten."
class WarriorManager
{
public static boolean fight(Warrior w1, Warrior w2)
{
return w1.power > w2.power;
}
public static boolean fight(List<Warrior> w1, List<Warrior> w2)
{
return …
}
}
ArrayList<MagicWarrior> magi = new ArrayList<MagicWarrior>();
for(int i = 0; i < 10; i++)
magi.add(new MagicWarrior());
ArrayList<ArcherWarrior> archers = new ArrayList<ArcherWarrior>();
for(int i = 0; i < 10; i++)
archers.add(new ArcherWarrior());
boolean isMagicCooler = WarriorManager.fight(magi, archers); // Compilation error!
"Maar hier kom je een compilatiefout tegen en vraag je je af wat er mis zou kunnen zijn."
"Het punt is dat MagicWarrior Warrior erft , en MagicWarrior-objecten kunnen worden doorgegeven aan de vechtmethode (Warrior, Warrior). "
"Maar List<MagicWarior> erft List<Warrior> niet . Dus je kunt het daar niet doorgeven!"
'Hoe bedoel je, het erft het niet?'
"Ik bedoel dit: de ene is een lijst en de andere is een lijst, maar ze hebben typeparameters."
"Je hebt gelijk. Ik merkte dat op de een of andere manier niet meteen op. Dus, is er al een oplossing voor dit probleem?"
"Ja. Je moet een complexere structuur gebruiken. Zo ziet het eruit:"
class WarriorManager
{
public static boolean fight(Warrior w1, Warrior w2)
{
return w1.power > w2.power;
}
public static boolean fight(List<? extends Warrior> w1, List<? extends Warrior> w2)
{
return …
}
}
"Het gedeelte «? Verlengt Warrior» betekent «elk type dat Warrior erft»»
"Met andere woorden, nu kun je een List<MagicWarrior> en een List<ArcherWarrior> doorgeven, en alles zal werken."
"Dat is zo geweldig. Hoe minder van dergelijke problemen, hoe beter."
"Zo voel ik me ook."
"Maar wat als ik niets nodig heb dat Warrior erft? Wat als ik elke lijst met elke typeparameter aan de methode wil doorgeven? Is dat toegestaan?"
"Ja, er zijn twee vormen van notatie om dat te doen:"
List<? extends Object>
List<?>
"Ze betekenen allebei hetzelfde, dus wordt meestal de tweede versie gebruikt."
"Dat is alles voor vandaag."
"Dank je, Ellie. Ik heb echt veel geleerd vandaag."
GO TO FULL VERSION