— Salom! Men Ellie'ning Generic’lar haqidagi leksiyasini davom ettiraman. Eshitishga tayyormisan?
— Ha.
— Bo'ldi, boshlaymiz.
Birinchi fakt. Metodlarning ham o'zlarining turlari, parametrlar bo'lishi mumkin.
— Ha, bilaman.
— Yo'q, men aynan o'z turlari, parametrlarini nazarda tutyapman: o'z turlari, parametrlar:
class Calculator
{
T add(T a, T b); //qo'shish
T sub(T a, T b); //ayirish
T mul(T a, T b); //ko'paytirish
T div(T a, T b); //bo'lish
}
Bu aynan metodlarning o'z turlari, parametrlaridir. Klassda parametrlar yo'q. Metodlarni statik deb e'lon qilib, objektsiz chaqirish mumkin.
— Tushunarli. Metoddagi turlar, parametrlar klasslardagi kabi ma'noga ega ekanmi?
— Ha. Lekin yangi narsalar ham bor.
Sening bilishing bo'yicha, tur tavsifida wildcard ishlatish mumkin. Shunda tasavvur qil:
public void doSomething(List<? extends MyClass> list)
{
for(MyClass object : list)
{
System.out.println(object.getState()); //bu yerda hammasi yaxshi ishlaydi.
}
}
Mana endi, agar kolleksiyaga yangi element qo'shishni xohlasak nima bo'ladi:
public void doSomething(List<? extends MyClass> list)
{
list.add(new MyClass()); //xato!
}
Gap bunda shundaki, umumiy holda doSomething metodiga List'ning element turlari MyClass emas, balki MyClass'ning har qanday vorisi bo'lishi mumkin. Bunday ro'yxatga MyClass obyektini qo'shib bo'lmaydi!
— Ha. Endi nima qilish kerak?
— Hech narsa. To'g'ridan-to'g'ri bu vaziyatda hech narsa qila olmaysiz. Lekin bu Java ishlab chiqaruvchilariga mulohaza qilish imkoniyatini berdi. Va ular yangi kalit so'zni - super o'ylab topishdi.
Uni ishlatish deyarli shunday ko'rinadi:
List<? super MyClass> list
Lekin extends va super orasida katta farq bor.
«? extends T» bu klass T'ning vorisi bo'lishi kerakligini anglatadi.
«? super T» bu klass T'ning ajdodi bo'lishi kerakligini anglatadi.
— E, qiziq. Bu qaerda ishlatiladi?
— «? super T» metod T turidagi obyektni kolleksiyaga qo’shmoqchi bo'lganda ishlatiladi. Shunda bu T yoki har qanday T ajdod turidagi kolleksiya bo'lishi mumkin.
— Ha. T turidagi obyektga havola har qanday T ota-onasiga tayinlanishi mumkin.
— Rostini aytsam – bu usul ko'p ishlatilmaydi. Ayniqsa, uning orqa tomoni ham bor. Misol:
public void doSomething(List<? super MyClass> list)
{
for(MyClass object : list) //xato!
{
System.out.println(object.getState());
}
}
public void doSomething(List<? super MyClass> list)
{
list.add(new MyClass()); //bu yerda hammasi yaxshi ishlaydi.
}
Endi birinchi misol ishlamaydi.
Chunki list kolleksiyasi hatto List<Object> (Object MyClass'ning eng yuqori ota-ona) bo'lishi mumkin, shuning uchun biz bunday kod yozmoqdamiz, va bunday yozib bo'lmaydi:
List<Object> list;
for(MyClass object : list) //xato!
{
System.out.println(object.getState());
}
— Tushunarli. Qiziqarli leksiya uchun rahmat.
— Iltimos.
GO TO FULL VERSION