“現在介紹一個有趣的新話題:通配符。”
“從本質上講,這就像一個 «*» 模式,可以匹配任何東西。”
“但讓我們從頭開始吧。”
“想像一下,你有一個 Warrior 類和一個方法來確定兩個戰士中哪個更強。這看起來可能是這樣的:”
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。。 ”
“這有點簡單,但舉個例子,它就可以了。”
“好的。”
“現在假設你已經決定為多個戰士加入戰鬥的情況制定類似的方法。”
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,但它們有類型參數。”
“你說得對。我不知道為什麼沒有第一時間注意到這一點。那麼,這個問題已經有解決方案了嗎?”
“是的。你需要使用更複雜的結構。它看起來是這樣的:”
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<?>
“它們的意思相同,所以通常使用第二個版本。”
“今天就這些了。”
“謝謝你,艾莉,我今天真的學到了很多東西。”