Polimorfizm — OOP ning uchinchi ustuni: bitta chaqiruv turli obyektlarda turlicha ishlashi. C++ kabi statik tillarda buning uchun virtual kalit so’zi kerak bo’ladi, Ruby’da esa bu standart xatti-harakat — hech qanday maxsus e’lon talab qilinmaydi.
Polimorfizm — bir xil metod chaqiruvining turli sinf obyektlarida o’ziga xos natija berish qobiliyati. Ruby’da barcha metod chaqiruvlari dinamik hal qilinadi — obyektning haqiqiy sinfiga qarab to’g’ri metod avtomatik tanlanadi.
Meros orqali polimorfizm
Bir xil metod nomi turli bola sinflarda turlicha ishlaydi — hech qanday qo’shimcha kalit so’zsiz:
class Hayvon
def ovoz
"Noma'lum ovoz"
end
end
class Mushuk < Hayvon
def ovoz
"Miyov"
end
end
class It < Hayvon
def ovoz
"Vov"
end
end
[Hayvon.new, Mushuk.new, It.new].each do |hayvon|
puts hayvon.ovoz
end
Noma'lum ovoz
Miyov
Vov
Bir xil hayvon.ovoz chaqiruvi har bir obyektda o’zining sinfiga mos natija berdi — C++’dagi virtual, Ruby’da hamma metod uchun tabiiy ravishda ishlaydi.
Duck typing — merosdan tashqari polimorfizm
Ruby’da polimorfizm uchun umumiy ota sinf shart emas — muhimi, obyekt kerakli metodga javob berishi:
class Papagay
def ovoz
"Salom!"
end
end
class Signalizatsiya
def ovoz
"Wii-uuu!"
end
end
[Papagay.new, Signalizatsiya.new].each do |narsa|
puts narsa.ovoz
end
Salom!
Wii-uuu!
Papagay va Signalizatsiya — bir-biriga umuman aloqasi yo’q sinflar, umumiy ota ham yo’q. Lekin ikkalasida ham ovoz metodi bor bo’lgani uchun ular bir xil kodda muammosiz ishlatildi. Bu — duck typing: “agar u o’rdakdek yursa va o’rdakdek g’oz-g’oz qilsa, u o’rdak hisoblanadi” tamoyili. Ruby’da tur emas, xatti-harakat (qaysi metodga javob bera olishi) muhim.
respond_to? — obyekt metodga javob bera oladimi
Duck typing bilan ishlaganda, obyektning kerakli metodga ega ekanini oldindan tekshirish foydali:
narsalar = [Papagay.new, "oddiy satr", 42]
narsalar.each do |narsa|
if narsa.respond_to?(:ovoz)
puts narsa.ovoz
else
puts "#{narsa.class} ovoz chiqara olmaydi"
end
end
Salom!
String ovoz chiqara olmaydi
Integer ovoz chiqara olmaydi
respond_to?(:ovoz) — obyektda ovoz metodi bor-yo’qligini xavfsiz tekshiradi, mos kelmasa dastur qulamaydi. Bu duck typing’ni amaliyotda xavfsiz qo’llashning standart usuli.
Statik va dinamik polimorfizm farqi
Ikki yondashuvni jadvalda solishtiramiz:
| Jihat | C++ (statik til) | Ruby (dinamik til) |
|---|---|---|
| Kerakli e’lon | virtual kalit so’zi |
shart emas — standart |
| Umumiy ota sinf | odatda talab qilinadi | shart emas (duck typing) |
| Tekshiruv vaqti | kompilyatsiyada | ijro paytida (runtime) |
Ruby’ning bu erkinligi kodni moslashuvchan qiladi, ammo mas’uliyatni ham oshiradi: xato faqat dastur ishga tushgach, aynan o’sha metod chaqirilganda ma’lum bo’ladi.