— Amigo, kitlarni yoqtirasanmi?
— Kitlar? Yo'q, eshitmaganman.
— Bu qandaydir sigirga o'xshaydi, faqat kattaroq va suzadi. Aytgancha, kitlar sigirlardan kelib chiqqan. Yo, ularda umumiy ajdod bo'lgan. Bu qadar muhim emas.
— Xo'sh. Senga OOP ning yana bir kuchli quroli — bu polimorfizm haqida gapirmoqchiman. Uning o'ziga xos tomonlari bor.
1) Metodning qayta yozilishi.
O'yin uchun "Sigir" klassini yozganingni tasavvur qil. Unda ko'p maydonlar va metodlar bor. Ushbu klass ob'ektlari turli narsalar qilishlari mumkin: yurish, ovqatlanish, uxlash. Boshqacha aytganda, sigirlar yurib yurganda qo'ng'iroqqa chalinadi. Faraz qilaylik, sen klassda hamma narsani noziklik bilan amalga oshirding.
Va endi loyihaning buyurtmachisi kelib, o'yinning yangi darajasini chiqarishni istaydi, bu yerda barcha harakatlar dengizda sodir bo'ladi va bosh qahramon kit bo'ladi.
Siz "Kit" klassini loyihalashtirishni boshladingiz va u faqat "Sigir" klassidan biroz farq qilishini tushundingiz. Har ikkala klassning ish mantig'i juda o'xshash, shuning uchun siz meros olishni qaror qildingiz.
"Sigir" klassi klass ota roliga a'lo darajada mos keladi, unda kerakli o'zgaruvchilar va metodlar mavjud. Faqat kitning suzish imkoniyatini qo'shish kifoya. Ammo muammo bor: sizning kitingizda oyoqlar, shoxlar va qo'ng'iroqlar bor. Chunki bu funksionallik "Sigir" klassi ichida amalga oshirilgan. Bu yerda nima qilish mumkin?
Bizga metodlarni o'zgartirish (almaşdırish) yordamga keladi. Agar biz meros olishgan metodimiz yangi klassda kerakli narsani qilmasa, biz bu metodni boshqasiga almashtira olamiz.
Bu qanday amalga oshiriladi? Bizning voris klassimizda, ota klassimizdagi o'zgartirmoqchi bo'lgan metod bilan bir xil metodni e'lon qilamiz. Yangi kodni yozamiz. Va hammasi — ota klassidagi eski metod go'yo yo'q bo'lib ketganday.
Bu qanday ishlaydi:
| Kod | Tavsif |
|---|---|
|
Bu yerda ikki klass aniqlangan Cow va Whale. Whale manaviyatni Cow dan olgan.
|
|
Ushbu kod ekranga «Я – корова» yozuvini chiqaradi. |
|
Ushbu kod ekranga «Я – кит» yozuvini chiqaradi |
Cow klassini voris qilib olish va printName metodini qayta yozishdan so'ng, Whale klassi amalda quyidagi ma'lumotlar va metodlar bilan boyidi:
| Kod | Tavsif |
|---|---|
|
Biz eski metod haqida hech narsa bilmaymiz. |
— To'g'ri aytdim, kutilganday.
2) Ammo hali hammasi emas.
— Cow klassida printAll metodini tasavvur qilaylik, u ikki boshqa metodni chaqiradi va kod quyidagicha ishlaydi:
Ekranda Я – белая Я – кит yozuvi chiqadi.
| Kod | Tavsif |
|---|---|
|
|
|
Ekranga quyidagi yozuv chiqadi: Я – белая Я – кит |
Diqqat eting, Cow klassida yozilgan printAll() metodi boshlangan ob'ekti Whale tipi bo'lganida, u Whale klassidagi printName metodidan foydalanadi, Cow emas.
Muhimi shundaki, metod qaysi klassda yozilgan emas, balki qaysi ob'ekt tipi (klass) metodni chaqirishi muhim.
— Yaqqol.
— Meros olish va qayta yozishni faqat statik bo'lmagan metodlar bilan amalga oshirish mumkin. Statik metodlar meros bo'lmaydi va, shuning uchun, qayta yozilmaydi.
Mana metod meros olish va qayta yozilishi natijasida Whale klassi qanday ko'rinadi:
| Kod | Tavsif |
|---|---|
|
Mana Whale klassi qanday ko'rinadi, meros olish va metodni qayta yozish natijasida. EskiprintName metod haqida biz hech narsa bilolmaymiz. |
3) Tiplarga moslash.
Bu yerda yanada qiziqarli moment bor. Chunki klass meros olishda ota klassining barcha metodlari va ma'lumotlarini oladi, bu klass ob'ekti ota klassi (va ota ota klassi, va hokazo, Object ga qadar) klassi o'zgaruvchilariga saqlanishi (tayinlanishi) ruxsat etiladi. Misol:
| Kod | Tavsif |
|---|---|
|
Ekranda yozuv: Я – белая |
|
Ekranda yozuv: Я – белая |
|
Ekranda yozuv: Whale@da435a Metod toString() Object klassdan meros qilingan. |
— Juda qiziqarli. Bu nima uchun kerak bo'lishi mumkin?
— Bu qimmatli xususiyat. Keyinchalik siz juda, juda qimmatli ekanini tushunasiz.
4) Ob'ekt metodi chaqirishi (metodlarning dinamik dispetcherlash).
Bu qanday ko'rinishga ega:
| Kod | Tavsif |
|---|---|
|
Ekranda yozuv: Я – кит. |
|
Ekranda yozuv: Я – кит. |
E'tibor bering, Cow yoki Whale klassidan printName metodi chaqirilib kelingani o'zgaruvchining turi emas, balki u qaysi ob'ekt tipiga (klassiga) bog'langanligi ta'sir qiladi.
Тип Cow o'zgaruvchisida Whale ob'ektiga havola saqlangan, va Whale klassida yozilgan printName metodi chaqiriladi.
— Bu tushunish uchun oson emas.
— Ha, bu juda ravshan emas. Asosiy qoida esda saqlang:
O'zgaruvchi uchun chaqiriladigan metodlar to'plami o'zgaruvchi tipiga qarab belgilanadi. Ammo qaysi metod/qaysi amalga oshirish chaqiriladi, ob'ekt tipi/klassining qaysi o'zgaruvchi uchun havola saqlanganligiga qarab belgilanadi.
— Sinab ko'raman.
— Siz doim bu bilan uchrashasiz, shuning uchun tez orada tushunasiz va hech qachon unutmaysiz.
5) Tiplarning kengayishi va torayishi.
Ma'lumot turlari uchun, ya'ni klasslar uchun, tiplarga moslash primitiv turlar uchun bo'lgani kabi ishlamaydi. Garchi ma'lumot turlarida ham kengayish va torayish turi mavjud. Misol:
| Kengayish turi | Tavsif |
|---|---|
|
Klassik kengayish turi. Endi kitni umumlashtirdik (kengaytirdik) sigirga, Ammo Whale tipidagi ob'ekt uchun faqat Cow klassida yozilgan metodlar chaqirilishi mumkin. Kompyuter cow o'zgaruvchisida faqat Cow klassida mavjud bo'lgan metodlarni chaqirishga izin beradi. |
| Torayish turi | Tavsif |
|---|---|
|
Klassik torayish turi bilan tekshiriladi. Cow tipidagi cow o'zgaruvchida Whale klassi ob'ektiga havola saqlangan.Biz buni aniq bilishga harakat qilamiz, va undan keyin sifatlar va torayishni amalga oshiramiz (saf'sarloq). Yoki boshqacha aytganda — downcast. |
|
Havola turini toraytirish turini tekshirmasdan ham amalga oshirilishi mumkin. Shu bilan cow o'zgaruvchisida Whale turidagi ob'ekt saqlanmagan bo'lsa, InvalidClassCastException istisnosini yuzaga keltiradi. |
6) Va endi yana bir misol. Asl metod chaqiruvi
Ba'zada meros bo'lgan metodni o'zgartirmasdan, balki faqat ozgina qo'shishlar kiritishni xohlaysiz.
Bunday holda, yangi metodda o'z kodingizni bajarib, ammo asosiy klass metodi orqali chaqirishni xohlaysiz. Va bu Java-da mumkin. Bu shunday amalga oshiriladi: super.method().
Misollar:
| Kod | Tavsif |
|---|---|
|
|
|
Ekranda yozuv: Я – белый Bu haqiqat emas: Я – корова Men kitman |
— Gm. Juda qiziqarli leksiya bo'ldi. Mening robot quloqlarim juda qizg'anishdi.
— Ha, bu oson material emas, bu eng murakkablaridan biri. Professor boshqa mualliflarning materiallariga havolalarni tashlashni va'da qildi, shunda tushunmagan narsalarni to'ldirish uchun imkoniyatingiz bo'ladi.
GO TO FULL VERSION