“現在介紹一個有趣的新話題:通配符。”

“從本質上講,這就像一個 «*» 模式,可以匹配任何東西。”

“但讓我們從頭開始吧。”

“想像一下,你有一個 Warrior 類和一個方法來確定兩個戰士中哪個更強。這看起來可能是這樣的:”

示例 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。。

“這有點簡單,但舉個例子,它就可以了。”

“好的。”

“現在假設你已經決定為多個戰士加入戰鬥的情況制定類似的方法。”

示例 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!

“但在這裡你遇到了一個編譯錯誤,並且對可能出了什麼問題感到困惑。”

“關鍵是MagicWarrior 繼承了 Warrior,而 MagicWarrior 對象可以傳遞給 fight(Warrior, Warrior) 方法。”

“但是List<MagicWarior> 不繼承 List<Warrior>。所以,你不能把它傳遞到那裡!”

“你說它不繼承是什麼意思?”

“我的意思是:一個是List,另一個是List,但它們有類型參數。”

“你說得對。我不知道為什麼沒有第一時間注意到這一點。那麼,這個問題已經有解決方案了嗎?”

“是的。你需要使用更複雜的結構。它看起來是這樣的:”

示例 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 …
 }
}

“«? extends Warrior» 部分錶示 «任何繼承 Warrior 的類型»”

“換句話說,現在你可以傳遞一個 List<MagicWarrior> 和一個 List<ArcherWarrior>,一切都會起作用。”

“太厲害了,這種問題越少越好。”

“我也是這種感覺。”

“但是,如果我不需要繼承 Warrior 的東西怎麼辦?如果我希望能夠將具有任何類型參數的任何 List 傳遞給該方法怎麼辦?這允許嗎?”

“是的,有兩種形式的符號可以做到這一點:”

List<? extends Object>
List<?>

“它們的意思相同,所以通常使用第二個版本。”

“今天就這些了。”

“謝謝你,艾莉,我今天真的學到了很多東西。”