„Сега нова, интересна тема: заместващи символи.“

„По същество това е нещо като шаблон „*“, който съвпада с всичко.“

— Но да започнем отначало.

„Представете си, че имате клас Warrior и метод, който определя кой от двама воини е по-силен. Ето How може да изглежда това:“

Пример 1
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 към битката.“

Пример 1
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 изглежда:“

Пример 1
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.“

"Това е всичко за днес."

„Благодаря ти, Ели. Наистина научих много днес.“