JavaRush /Kurslar /All lectures for UZ purposes /Kirish modifikatorlari, metodlarni qayta yozish, abstrakt...

Kirish modifikatorlari, metodlarni qayta yozish, abstrakt metodlarni amalga oshirish

All lectures for UZ purposes
Daraja, Dars
Mavjud

— Men senga «kirish modifikatorlari» haqida gapirib beraman. Bir vaqtlar men ularni senga aytib berganman, ammo takrorlash – bilimning onasi.

Sening klass o'zgaruvchilaring va metodlaring boshqa klasslardan kirishini (ko'rinishini) boshqarishing mumkin. Kirish modifikatori "Qaysi metodga/qaysi o'zgaruvchiga kim murojaat qila oladi?" degan savolga javob beradi. Har bir metod yoki o'zgaruvchiga faqat bitta modifikator belgilash mumkin.

1) «public» modifikatori.

public modifikatori bilan belgilangan o'zgaruvchi, metod yoki klassga dasturdagi istalgan joydan murojaat qilish mumkin. Bu eng yuqori darajada ochiqlik – hech qanday cheklovlar yo'q.

2) «private» modifikatori.

private modifikatori bilan belgilangan o'zgaruvchi, metod yoki klassga faqat o'sha klassning o'zidan murojaat qilinishi mumkin. Barcha boshqa klasslar uchun belgilangan metod yoki o'zgaruvchi – ko'rinmas. Bu eng yuqori darajada yopiqlik – faqat o'z klassi. Bunday metodlar meros qilib olinmaydi va qayta yozilmaydi. Ularga o'rnidan kirish ham mumkin emas.

3) «Modifikator «defolt».

Agar o'zgaruvchi yoki metod hech qaysi modifikator bilan belgilangan bo'lmasa, demak, ular «defolt modifikatori» bilan belgilangan hisoblanadi. Bunday modifikator bilan o'zgaruvchilar va metodlar, ular belgilangan paketin barcha klasslari uchun ko'rinadi va faqat ularga. Bu modifikatorni "package" yoki "package private" deb ham atashadi, ya'ni kirish paketin barcha klasslariga ochilgan.

4) «protected» modifikatori.

Bu kirish darajasi biroz kengroq, package dan. protected modifikatori bilan belgilangan o'zgaruvchi, metod yoki klassga uning o'z paketi (package kabi) va undan meros olgan barcha klasslardan kirish mumkin.

Izoh bilan jadval:

Ko'rinish turi Kalit so'z Kirish
O'z klassi O'z paketi Klass — meros oluvchi Barcha klasslar
Yopiq private Bor Yo'q Yo'q Yo'q
Packet (modifikator yo'q) Bor Bor Yo'q Yo'q
Himoyalangan protected Bor Bor Bor Yo'q
Ochiq public Bor Bor Bor Bor

Bu jadvalni oson eslab qolish usuli bor. O'zingizdan xuddi bir vasiyatnoma tuzib, barcha narsalarni to'rt toifaga ajratayotganingizni tasavvur qiling. Kim sizning narsalaringizdan foydalanishi mumkin?

Kim kirishi mumkin Modifikator Misol
Faqat o'zim private Shaxsiy kundalik
Oila (modifikator yo'q) Oilaviy suratlar
Oila va meros oluvchilar protected Oilaviy mulk
Hammaga public Xotiralar

— Va agar bir oilani bir paketda joylashgan klasslar deb tasavvur qilsa, juda ham o'xshash.

— Shuningdek, senga metodlarni qayta yozish bo'yicha bir nechta qiziqarli narsalarni aytmoqchiman.

1) Abstrakt metodni noaniq amalga oshirish.

Faraz qilamiz, senga kod bor:

Kod
class Cat
{
 public String getName()
 {
  return "Vaska";
 }
}

Va sen undan Tiger klassini meros qilib olayotganda yangi klassga interfeys qo'shmoqchi bo'lding

Kod
class Cat
{
 public String getName()
 {
   return "Vaska";
 }
}
interface HasName
{
 String getName();
 int getWeight();
}
class Tiger extends Cat implements HasName
{
 public int getWeight()
 {
  return 115;
 }

}

Agar sen faqat Intellij IDEA tomonidan ko'rsatilgan barcha mavjud metodlarni amalga oshirsang, keyin xatoni uzoq qidirib topishing mumkin.

Ma'lum bo'ldiki, Tiger klassida Catdan olingan getName metodi mavjud va u HasName interfeysi uchun getName metodi deb hisoblanadi.

— Men buni qo'rqinchli deb bilmayman.

— Bu yaxshi emas, bu ko'proq xato qilish uchun potentsial joy.

Lekin undan ham yomon bo'lishi mumkin:

Kod
interface HasWeight
{
 int getValue();
}
interface HasSize
{
 int getValue();
}
class Tiger extends Cat implements HasWeight, HasSize
{
 public int getValue()
 {
  return 115;
 }
}

Ma'lum bo'ldiki, sen har doim bir nechta interfeysdan meros ololmaysan. To'g'ri, meros olish mumkin, lekin ularni to'g'ri amalga oshirish – yo'q. Misolga qarang, ikkala interfeys ham sen getValue() metodini amalga oshirishingni talab qilmoqda va nima qaytarishi kerakligi aniq emas: vaznmi (weight) yoki o'lchammi (size). Bu juda noqulay narsa, agar sen bunga duch kelsang.

— Ha, rozi bo'ldim. Metodni amalga oshirmoqchisan, lekin mumkin emas. Birdan sen allaqachon bazaviy klassdan shunday nomdagi metodni meros qilib olding. Buzildi.

— Lekin yaxshi xabarlar bor.

2) Ko'rinishning kengayishi. Metodni qayta yozishda ko'rinishni kengaytirishga ruxsat beriladi. Mana bu qanday ko'rinishda:

Java kod Ta'rif
class Cat
{
 protected String getName()
 {
  return "Vaska";
 }
}
class Tiger extends Cat
{
 public String getName()
 {
  return "Vasiliy Tigranovich";
 }
}
Biz metodning ko'rinishini protected dan public gacha kengaytirdik.
Qo'llanilishi Nega bu "qonuniy"
public static void main(String[] args)
{
 Cat cat = new Cat();
 cat.getName();
}
Hammasi yaxshi. Bu yerda biz hatto metod ko'rinishi meros oluvchi klassda kengaytirilganini bilmaymiz.
public static void main(String[] args)
{
 Tiger tiger = new Tiger();
 tiger.getName();
}
Bu yerda ko'rinishni kengaytirilgan metod chaqiriladi.

Agar bu mumkin bo'lmasa, har doim Tiger'da metodni e'lon qilishingiz mumkin edi:
public String getPublicName()
{
super.getName(); //protected metod chaqirildi
}

Ya'ni hech qanday xavfsizlikni buzish haqida gap yo'q.

public static void main(String[] args)
{
 Cat catTiger = new Tiger();
 catTiger.getName();
}
Agar barcha shartlar bazaviy turdagi metodni (Cat) chaqirish uchun mos keladigan bo'lsa, ular albatta meros oluvchi turini chaqirish uchun mos keladi (Tiger). Metod chaqiruviga cheklovlar kuchaytirilmadi, aksincha yumshatildi.

— To'liq tushundim, deb ishonch hosil qilmayman, lekin buni amalga oshirish mumkinligini eslab qolaman.

3) Natija turini toraytirish.

Qayta yozilgan metodda biz natija turini toraytirishimiz mumkin.

Java kod Ta'rif
class Cat
{
 public Cat parent;
 public Cat getMyParent()
 {
  return this.parent;
 }
 public void setMyParent(Cat cat)
 {
  this.parent = cat;
 }
}
class Tiger extends Cat
{
 public Tiger getMyParent()
 {
  return (Tiger) this.parent;
 }
}
Biz getMyParent metodini qayta yozdik, endi u Tiger turidagi ob'ektni qaytaradi.
Qo'llanilishi Nega bu "qonuniy"
public static void main(String[] args)
{
 Cat parent = new Cat();

 Cat me = new Cat();
 me.setMyParent(parent);
 Cat myParent = me.getMyParent();
}
Hammasi yaxshi. Bu yerda biz hatto meros oluvchi klassda getMyParent metodining natija turi toraytirilganini bilmaymiz.

"Eski kod" nima qilsa, shunday ishlaydi.

public static void main(String[] args)
{
 Tiger parent = new Tiger();

 Tiger me = new Tiger();
 me.setMyParent(parent);
 Tiger myParent = me.getMyParent();
}
Bu yerda natija turi toraytirilgan metod chaqiriladi.

Agar buni amalga oshirish imkoni bo'lmasa, har doim Tiger'da metodni e'lon qilishingiz mumkin edi:
public Tiger getMyTigerParent()
{
return (Tiger) this.parent;
}

Ya'ni hech qanday xavfsizlikni buzish va/yoki turga mos kelmaslik haqida gap yo'q.

public static void main(String[] args)
{
 Tiger parent = new Tiger();

 Cat me = new Tiger();
 me.setMyParent(parent);
 Cat myParent = me.getMyParent();
}
Bu yerda ham hammasi yaxshi ishlaydi, garchi biz o'zgaruvchilar turini bazaviy klassga (Cat) kengaytirdik.

Hech qanday muammo yo'q getMyParent metodi chaqirilganda, chunki uning natijasi, garchi Tiger klassiga tegishli bo'lsa ham, hali ham myParent bazaviy klass (Cat) o'zgaruvchisi uchun yaxshi tayinlanishi mumkin.

Tiger ob'ektlarini Tiger klassida ham, Cat klassida ham o'zgaruvchilarda saqlash mumkin.

— Ha. Men tushundim. Metodlarni qayta yozishda, bizning ob'ektlarimizni faqat bazaviy klass bilan ishlay oladigan kodga topshirganimizda, hammasi qanday ishlashini o'ylashimiz kerak.

— Aynan shunday! Shunday qilib, savol: nima uchun metodni qayta yozishda natija turini kengaytira olmaysiz?

— Bu aniq, keyin bazaviy klassdagi kod ishlamaydi:

Java kod Muammo izohi
class Cat
{
 public Cat parent;
 public Cat getMyParent()
 {
  return this.parent;
 }
 public void setMyParent(Cat cat)
 {
  this.parent = cat;
 }
}
class Tiger extends Cat
{
 public Object getMyParent()
 {
  if (this.parent != null)
   return this.parent;
  else
   return "men yetimman";
 }
}
Biz getMyParent metodini qayta yozdik va natija turini kengaytirdik.

Bu yerda hammasi yaxshi.

public static void main(String[] args)
{
 Tiger parent = new Tiger();

 Cat me = new Tiger();
 Cat myParent = me.getMyParent();
}
O'shanda bizning bu kod ishlamay qoladi.

getMyParent metodi chaqirilishi mumkin, chunki u aslida Tiger tipidagi ob'ektda chaqirilmoqda.

Va biz tayinlashdan oldin hech qanday tekshirishga ega emasmiz. Demak, myParent tipidagi Cat o'zgaruvchisi satr uchun havola saqlashi mumkin bo'lish ehtimoli bor.

— Ajoyib misol, Amigo!

Java-da metod chaqirishdan oldin, ob'ektda bunday metod bor yoki yo'qligi tekshirilmaydi. Barcha tekshiruvlar bajarilayotgan vaqtida sodir bo'ladi. Va [gipotezikal] mavjud bo'lmagan metod chaqirishi ehtimoli bor, dastur kodini mavjud bo'lmagan joyda bajarishga olib keladi. Bu, oxir-oqibat, fojiali xatoga olib keladi va operatsion tizim dasturni majburiy yakuni qiladi.

— Bu qiziq. Bilaman.

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