„Сега нова, интересна тема: заместващи символи.“
„По същество това е нещо като шаблон „*“, който съвпада с всичко.“
— Но да започнем отначало.
„Представете си, че имате клас Warrior и метод, който определя кой от двама воини е по-силен. Ето How може да изглежда това:“
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 и ArcherWarrior наследяват Warrior. .“
„Малко е опростено, но за пример ще свърши работа.“
"ДОБРЕ."
„А сега да предположим, че сте решor да направите подобен метод за ситуацията, в която множество воини са се присъединor към битката.“
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!
„Но тук срещате грешка при компorране и сте озадачени Howво може да не е наред.“
„Работата е там, че MagicWarrior наследява Warrior и обектите на MagicWarrior могат да бъдат предадени на метода fight(Warrior, Warrior).“
"Но List<MagicWarior> не наследява List<Warrior> . Така че не можете да го прехвърлите там!"
— Какво искаш да кажеш, че не го наследява?
„Имам предвид следното: единият е списък, а другият е списък, но те имат параметри за тип.“
„Прав си. НяHow си не забелязах това веднага. И така, има ли вече решение на този проблем?“
„Да. Трябва да използвате по-сложна структура. Ето How изглежда:“
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 …
}
}
„Частта «? разширява Warrior» означава «всеки тип, който наследява Warrior»"
„С други думи, сега можете да подадете List<MagicWarrior> и List<ArcherWarrior> и всичко ще работи.“
"Това е толкова страхотно. Колкото по-малко такива проблеми, толкова по-добре."
— И аз се чувствам така.
„Но Howво ще стане, ако нямам нужда от нещо, което наследява Warrior? Какво ще стане, ако искам да мога да предам всеки списък с произволен тип параметър към метода? Това разрешено ли е?“
„Да, има две форми на нотация за това:“
List<? extends Object>
List<?>
„И двете означават едно и също нещо, така че обикновено се използва втората version.“
"Това е всичко за днес."
„Благодаря ти, Ели. Наистина научих много днес.“
GO TO FULL VERSION