„Acum pentru un subiect nou, interesant: wildcards”.
„În esență, acesta este ceva ca un model «*» care se potrivește cu orice.”
— Dar să începem de la început.
„Imaginați-vă că aveți o clasă Războinici și o metodă care determină care dintre cei doi războinici este mai puternic. Iată cum ar putea arăta:”
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 și ArcherWarrior moștenesc amândoi Warrior. ”.
„Este puțin simplist, dar, de exemplu, va funcționa”.
"BINE."
„Acum să presupunem că ai decis să faci o metodă similară pentru situația în care mai mulți războinici s-au alăturat luptei.”
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!
„Dar aici întâmpinați o eroare de compilare și sunteți nedumerit cu privire la ce ar putea fi greșit.”
„Chestia este că MagicWarrior moștenește Warrior , iar obiectele MagicWarrior pot fi transmise metodei de luptă (Warrior, Warrior).
„Dar List<MagicWarior> nu moștenește List<Warrior> . Deci, nu poți să-l treci acolo!”
„Ce vrei să spui că nu o moștenește?”
„Vreau să spun asta: una este o Listă și cealaltă este o Listă, dar au parametri de tip”.
"Ai dreptate. Cumva nu am observat asta imediat. Deci, există deja o soluție pentru această problemă?"
"Da. Trebuie să folosești o structură mai complexă. Așa arată:"
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 …
}
}
„Partea „? extinde Războinic” înseamnă „orice tip care moștenește Războinic””
„Cu alte cuvinte, acum poți trece o Listă<MagicWarrior> și o Listă<ArcherWarrior> și totul va funcționa.”
"Este atât de grozav. Cu cât sunt mai puține astfel de probleme, cu atât mai bine."
— Așa mă simt și eu.
"Dar dacă nu am nevoie de ceva care să-l moștenească pe Warrior? Ce se întâmplă dacă vreau să pot transmite metodei orice Listă cu orice parametru de tip? Este permis?"
„Da, există două forme de notație pentru a face asta:”
List<? extends Object>
List<?>
„Amândoi înseamnă același lucru, așa că de obicei se folosește a doua versiune.”
— Asta-i tot pentru azi.
— Mulțumesc, Ellie. Chiar am învățat multe astăzi.
GO TO FULL VERSION