— Yangi qiziqarli mavzu — wildcards.
Mazmunan, bu xuddi har qanday narsaga mos keladigan "шаблон *".
Lekin keling uzoqdan boshlaymiz.
Tasavvur qiling, sizda «Warrior(Воин)» sinfi bor va ikkita jangchi qaysi biri kuchliroq ekanini hisoblaydigan usul. Masalan, bu quyidagicha ko‘rinishi mumkin:
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 va ArcherWarrior – Warrior ning merosxo'r sinflaridir.
Biroz sodda, lekin misol uchun yetadi.
— Ok.
— Endi, misol uchun, siz devorga-devor jangchilari bilan o'xshash usulni yaratishga qaror qildingiz.
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); //компиляция xatosi!
Bu erda siz kompilyatsiya xatosiga duch kelasiz va tushunmayapsiz, nima noto'g'ri?
Masala shundaki, MagicWarrior – Warrior ning merosxo'ridir va uning obyektlarini fight(Warrior, Warrior) usuliga o'tkazish mumkin
Lekin List<MagicWarrior> — bu List<Warrior> ning merosxo'ri emas. Uni o'sha yerga o'tkaza olmaysiz!
— Qanday qilib merosxo'r emas?
— Shunchaki. Biri List va boshqasi List. Parametrlar bilan bo'lsa ham.
— Ha, men bir payt o‘xshamayman deb e'tibor bermadim. Va bu muammoning allaqachon echimi bormi?
— Ha. Bu uchun murakkabroq tuzilma ishlatiladi. Bu quyidagicha ko'rinadi:
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 dan meros olgan har qanday tur» degan ma'noni anglatadi.
Ya'ni, u yerga List<MagicWarrior> ro'yxati va List<ArcherWarrior> ro'yxatini berishingiz mumkin, hammasi ishlaydi.
— Bu juda yaxshi. Shundagi muammolar qanchalik oz bo'lsa, shuncha yaxshi bo'ladi.
— Men ham shunday fikrdaman.
— Agar menga Warrior ning merosxo'ri kerak bo'lmasa-chi? Agar men usulga har qanday parameter bilan har qanday List ni o'tkazishni xohlasam-chi? Buni qilish mumkinmi?
— Ha, bu vaziyatni tavsiflash uchun ikkita yozuv mavjud:
List<? extends Object>
List<?>
Ular mazmunan ekvivalent, shuning uchun odatda ikkinchisini ishlatishadi.
Menda hammasi shu.
— Rahmat, Elly, bugun chindan ham ko'p yangiliklarni bilib oldim.
GO TO FULL VERSION