JavaRush /Kurslar /All lectures for UZ purposes /Polimorfizm va qayta yozish

Polimorfizm va qayta yozish

All lectures for UZ purposes
Daraja, Dars
Mavjud

— 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.

Polimorfizm va qayta yozish - 1

— 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.

Polimorfizm va qayta yozish - 2

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?

Polimorfizm va qayta yozish - 3

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.

Polimorfizm va qayta yozish - 4

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
class Cow {
  public void printColor() {
    System.out.println("Я - белая");
  }

  public void printName() {
    System.out.println("Я - корова");
  }
}

class Whale extends Cow {
  public void printName() {
    System.out.println("Я - кит");
  }
Bu yerda ikki klass aniqlangan Cow va Whale. Whale manaviyatni Cow dan olgan.






Whale klassida printName(); metodi qayta yozilgan.

public static void main(String[] args) {
  Cow cow = new Cow();
  cow.printName();
}
Ushbu kod ekranga «Я – корова» yozuvini chiqaradi.
public static void main(String[] args) {
  Whale whale = new Whale();
  whale.printName();
}
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
class Whale {
  public void printColor() {
    System.out.println("Я - белая");
  }

  public void printName() {
    System.out.println("Я - кит");
  }
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
class Cow {
  public void printAll() {
    printColor();
    printName();
  }

  public void printColor() {
    System.out.println("Я - белая");
  }

  public void printName() {
    System.out.println("Я - корова");
  }
}

class Whale extends Cow {
  public void printName() {
    System.out.println("Я - кит");
  }
public static void main(String[] args) {
  Whale whale = new Whale();
  whale.printAll();
}
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
class Whale {
  public void printAll() {
    printColor();
    printName();
  }

  public void printColor() {
    System.out.println("Я - белая");
  }

  public void printName() {
    System.out.println("Я - кит");
  }
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
public static void main(String[] args) {
  Whale whale = new Whale();
  whale.printColor();
}
Ekranda yozuv:
Я – белая
public static void main(String[] args) {
  Cow cow = new Whale();
  cow.printColor();
}
Ekranda yozuv:
Я – белая
public static void main(String[] args) {
  Object o = new Whale();
  System.out.println(o.toString());
}
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
public static void main(String[] args) {
  Whale whale = new Whale();
  whale.printName();
}
Ekranda yozuv:
Я – кит.
public static void main(String[] args) {
  Cow cow = new Whale();
  cow.printName();
}
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
Cow cow = new Whale();
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
Cow cow = new Whale();
if (cow instanceof Whale) {
  Whale whale = (Whale) cow;
}
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.
Cow cow = new Cow();
Whale whale = (Whale) cow; //exception
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
class Cow {
  public void printAll() {
    printColor();
    printName();
  }

  public void printColor() {
    System.out.println("Я – белый");
  }

  public void printName() {
    System.out.println("Я – корова");
  }
}

class Whale extends Cow {
  public void printName() {
    System.out.print("Bu haqiqat emas: ");
    super.printName();

    System.out.println("Men kitman");
  }
}
public static void main(String[] args){
  Whale whale = new Whale();
  whale.printAll();
}
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.

Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION