"์ด์ œ ์ƒˆ๋กญ๊ณ  ํฅ๋ฏธ๋กœ์šด ์ฃผ์ œ์ธ ์™€์ผ๋“œ์นด๋“œ์ž…๋‹ˆ๋‹ค."

"๋ณธ์งˆ์ ์œผ๋กœ ์ด๊ฒƒ์€ ๋ฌด์—‡์ด๋“  ์ผ์น˜ํ•˜๋Š” ยซ*ยป ํŒจํ„ด๊ณผ ๊ฐ™์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค."

"ํ•˜์ง€๋งŒ ์ฒ˜์Œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ฉ์‹œ๋‹ค."

"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> ๋ฅผ ์ƒ์†ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค . ๋”ฐ๋ผ์„œ ๊ฑฐ๊ธฐ์— ์ „๋‹ฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค!"

"๋ฌผ๋ ค๋ฐ›์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒŒ ๋ฌด์Šจ ๋œป์ด์•ผ?"

"์ œ ๋ง์€ ํ•˜๋‚˜๋Š” ๋ชฉ๋ก์ด๊ณ  ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ๋ชฉ๋ก์ด์ง€๋งŒ ์œ ํ˜• ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค."

"๋„ค ๋ง์ด ๋งž์•„. ์–ด์งธ์„œ์ธ์ง€ ๋ฐ”๋กœ ๋ˆˆ์น˜์ฑ„์ง€ ๋ชปํ–ˆ์–ด. ๊ทธ๋Ÿผ ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์€ ์ด๋ฏธ ์žˆ๋Š” ๊ฑฐ์ง€?"

"์˜ˆ. ๋” ๋ณต์žกํ•œ ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค."

์˜ˆ 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 โ€ฆ
 }
}

"? ์ „์‚ฌ ํ™•์žฅ" ๋ถ€๋ถ„์€ "์ „์‚ฌ๋ฅผ ๊ณ„์Šนํ•˜๋Š” ๋ชจ๋“  ์œ ํ˜•"์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค."

"์ฆ‰, ์ด์ œ List<MagicWarrior> ๋ฐ List<ArcherWarrior>๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋ชจ๋“  ๊ฒƒ์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค."

"๊ต‰์žฅํ•˜๋„ค์š”. ๊ทธ๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ์ ์„์ˆ˜๋ก ์ข‹์Šต๋‹ˆ๋‹ค."

"๋‚˜๋„ ๊ทธ๋Ÿฐ ๊ธฐ๋ถ„์ด์•ผ."

"ํ•˜์ง€๋งŒ Warrior๋ฅผ ์ƒ์†ํ•˜๋Š” ๊ฒƒ์ด ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ์œ ํ˜• ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์žˆ๋Š” ๋ชจ๋“  List๋ฅผ ๋ฉ”์†Œ๋“œ์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ์›ํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ํ•ฉ๋‹ˆ๊นŒ? ํ—ˆ์šฉ๋ฉ๋‹ˆ๊นŒ?"

"์˜ˆ, ๋‘ ๊ฐ€์ง€ ํ˜•์‹์˜ ํ‘œ๊ธฐ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค."

List<? extends Object>
List<?>

"๋‘˜ ๋‹ค ๊ฐ™์€ ๊ฒƒ์„ ์˜๋ฏธํ•˜๋ฏ€๋กœ ์ผ๋ฐ˜์ ์œผ๋กœ ๋‘ ๋ฒˆ์งธ ๋ฒ„์ „์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค."

"์˜ค๋Š˜์€ ๊ทธ๊ฒŒ ๋‹ค์•ผ."

"๊ณ ๋งˆ์›Œ ์—˜๋ฆฌ. ์˜ค๋Š˜ ์ •๋ง ๋งŽ์ด ๋ฐฐ์› ์–ด."