JavaRush /Java blogi /Random-UZ /Aniq misollar bilan Java-da mavhum sinflar

Aniq misollar bilan Java-da mavhum sinflar

Guruhda nashr etilgan
Salom! Oldingi ma'ruzalarda biz interfeyslar bilan tanishdik va ular nima uchun kerakligini aniqladik. Bugungi mavzu oldingi mavzu bilan umumiy narsaga ega bo'ladi. Keling , Java tilidagi abstrakt sinflar haqida gapiraylik .Aniq misollar bilan Java-da abstrakt sinflar - 1

Nima uchun sinflar "abstrakt" deb ataladi?

Ehtimol, siz "abstraksiya" nima ekanligini eslaysiz - biz buni allaqachon yopganmiz :) Agar siz to'satdan unutgan bo'lsangiz, yaxshi, eslaylik: bu OOP tamoyilidir , unga ko'ra sinflarni loyihalashda va ob'ektlarni yaratishda quyidagilar zarur: ob'ektning faqat asosiy xususiyatlarini ajratib ko'rsatish va ikkinchi darajalilarini olib tashlash. Misol uchun, agar biz sinfni - maktab o'qituvchisini loyihalashtirayotgan bo'lsak , biz " bo'ySchoolTeacher " xususiyatiga muhtoj emasmiz . Darhaqiqat: o'qituvchi uchun bu xususiyat muhim emas. Ammo dasturda sinf - basketbolchi yaratadigan bo'lsak, balandlik asosiy xususiyatlardan biriga aylanadi. Shunday qilib, mavhum sinf kelajakdagi sinflar guruhi uchun eng mavhum, taxminan "bo'sh" dir. Ushbu preparatni tayyor shaklda ishlatish mumkin emas - u juda "xom". Ammo u kelajakdagi sinflar - mavhum sinfning merosxo'rlari ega bo'ladigan ma'lum bir umumiy holat va xatti-harakatni tasvirlaydi. BasketballPlayer

Java abstrakt sinfiga misollar

Keling, mashinalar bilan oddiy misolni ko'rib chiqaylik:
public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public abstract void gas();

   public abstract void brake();

   public String getModel() {
       return model;
   }

   public void setModel(String model) {
       this.model = model;
   }

   public String getColor() {
       return color;
   }

   public void setColor(String color) {
       this.color = color;
   }

   public int getMaxSpeed() {
       return maxSpeed;
   }

   public void setMaxSpeed(int maxSpeed) {
       this.maxSpeed = maxSpeed;
   }
}
Eng oddiy mavhum sinf shunday ko'rinadi. Ko'rib turganingizdek, hech qanday maxsus narsa yo'q :) Bu bizga nima uchun kerak bo'lishi mumkin? Avvalo, u bizga kerak bo'lgan ob'ektni iloji boricha mavhum tarzda tasvirlaydi - mashina. Mavhum so'z bu erda biron bir sababga ko'ra mavjud. Dunyoda "shunchaki mashinalar" yo'q. Yuk mashinalari, poyga avtomobillari, sedanlar, kupelar, SUVlar mavjud. Bizning mavhum sinfimiz shunchaki "loyiha" bo'lib, undan keyin biz avtomobil sinflarini yaratamiz.
public class Sedan extends Car {

   @Override
   public void gas() {
       System.out.println("The sedan accelerates!");
   }

   @Override
   public void brake() {
       System.out.println("The sedan slows down!");
   }

}
Bu biz meros haqidagi ma'ruzalarda gaplashgan narsaga o'xshaydi. CarFaqat u yerda bizda mavhum bo'lmagan sinf va uning usullari mavjud edi. Ammo bu yechimning bir qator kamchiliklari bor, ular mavhum sinflarda tuzatiladi. Avvalo, mavhum sinfning namunasini yaratib bo'lmaydi:
public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Error! The Car class is abstract!
   }
}
Ushbu "hiyla" maxsus Java yaratuvchilari tomonidan amalga oshirilgan. Yana bir bor eslash kerak: mavhum sinf kelajakdagi "oddiy" sinflar uchun rejadir . Chizma nusxalari kerak emas, to'g'rimi? Shunday qilib, mavhum sinf misollarini yaratishga hojat yo'q :) Va agar sinf Carmavhum bo'lmasa, biz uning ob'ektlarini osongina yaratishimiz mumkin edi:
public class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       // some logic
   }

   public  void brake() {
       // some logic
   }
}


public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Everything is OK, the machine has been created
   }
}
Endi bizning dasturimizda qandaydir tushunarsiz mashina bor - yuk mashinasi emas, poyga mashinasi, sedan emas, umuman olganda. Tabiatda mavjud bo'lmagan o'sha "mashina". Xuddi shu misolni hayvonlar bilan ham keltirish mumkin. Tasavvur qiling-a, sizning dasturingizda ob'ektlar paydo bo'lganmi Animal- " shunchaki hayvon ". U qanday turdagi, qaysi oilaga tegishli, qanday xususiyatlarga ega ekanligi noma'lum. Uni dasturda ko'rish g'alati bo'lardi. Tabiatda "shunchaki hayvonlar" yo'q. Faqat itlar, mushuklar, tulkilar, mollar va boshqalar. Mavhum sinflar bizni " shunchaki ob'ektlar " dan ozod qiladi. Ular bizga asosiy holat va xulq-atvorni beradi. Misol uchun, barcha avtomobillar modeli , rangi va maksimal tezligiga ega bo'lishi kerak , shuningdek, ular gaz va tormozlash qobiliyatiga ega bo'lishi kerak . Ana xolos. Bu umumiy mavhum sxema, keyin siz o'zingiz kerakli sinflarni loyihalashtirasiz. Iltimos, diqqat qiling: abstrakt sinfdagi ikkita usul ham abstrakt sifatida belgilanadi va ular umuman amalga oshirilmaydi. Sababi bir xil: mavhum sinflar "oddiy mashinalar" uchun "standart xatti-harakat" ni yaratmaydi. Ular faqat barcha mashinalarni yasashlari kerakligini aytishadi. Biroq, agar siz hali ham standart xatti-harakatga muhtoj bo'lsangiz, usullarni mavhum sinfda qo'llashingiz mumkin. Java buni taqiqlamaydi:
public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       System.out.println("Let's go!");
   }

   public abstract void brake();

   //getters and setters
}


public class Sedan extends Car {

   @Override
   public void brake() {
       System.out.println("The sedan slows down!");
   }

}

public class Main {

   public static void main(String[] args) {

       Sedan sedan = new Sedan();
       sedan.gas();
   }
}
Konsol chiqishi: "Tezlashtiring!" Ko'rib turganingizdek, biz abstrakt sinfda bitta usulni amalga oshirdik, ikkinchisini amalga oshirmadik. Natijada, sinfimizning xatti-harakati Sedanikki qismga bo'lindi: agar siz unga usulni chaqirsangiz gas(), u ota-ona mavhum sinfdan "yuqoriga tortadi" Carva brake()biz sinfdagi usulni qayta belgilab oldik Sedan. Bu juda qulay va moslashuvchan bo'lib chiqdi. Ammo bizning sinfimiz unchalik mavhum emasmi ? Axir, aslida, uning usullarining yarmi amalga oshiriladi. Aslida - va bu juda muhim xususiyat - agar uning usullaridan kamida bittasi mavhum bo'lsa, sinf mavhumdir . Ikkitadan kamida bittasi, minglab usullardan kamida bittasi - bu muhim emas. Biz hatto barcha usullarni amalga oshirishimiz va mavhumlarini qoldirmasligimiz mumkin. Abstrakt usullarsiz mavhum sinf bo'ladi. Asosan, bu mumkin va kompilyator xato qilmaydi, lekin buni qilmaslik yaxshiroqdir: abstrakt so'zi o'z ma'nosini yo'qotadi va dasturchi hamkasblaringiz buni ko'rib juda hayron bo'lishadi:/ Bundan tashqari, agar usul mavjud bo'lsa . abstrakt so'zi bilan belgilanadi, har bir avlod sinfi amalga oshirilishi yoki mavhum deb e'lon qilinishi kerak. Aks holda kompilyator xatoga yo'l qo'yadi . Albatta, har bir sinf faqat bitta abstrakt sinfdan meros bo'lishi mumkin, shuning uchun meros bo'yicha abstrakt va oddiy sinflar o'rtasida farq yo'q. Abstrakt sinfdan yoki oddiy sinfdan meros olishimiz muhim emas, faqat bitta ota-ona sinf bo'lishi mumkin.

Nima uchun Java-da bir nechta sinf merosi yo'q?

Biz allaqachon Java-da ko'p meros yo'qligini aytdik, ammo nima uchun ekanligini aniqlay olmadik. Keling, buni hozir sinab ko'raylik. Gap shundaki, agar Java bir nechta merosga ega bo'lsa, bolalar sinflari qaysi xatti-harakatni tanlashni hal qila olmaydi. Aytaylik, bizda ikkita sinf bor - Tosterva NuclearBomb:
public class Toster {


 public void on() {

       System.out.println("The toaster is on, the toast is getting ready!");
   }

   public void off() {

       System.out.println("The toaster is off!");
   }
}


public class NuclearBomb {

   public void on() {

       System.out.println("Взрыв!");
   }
}
Ko'rib turganingizdek, ikkala usul ham mavjud on(). Toster bo'lsa, u tost pishirishni boshlaydi, yadroviy bomba bo'lsa, u portlashni keltirib chiqaradi. Oh :/ Endi tasavvur qiling-a, siz (men nima uchun birdaniga bilmayman!) O'rtada biror narsa yaratishga qaror qildingiz. Va bu sizning sinfingiz - MysteriousDevice! Bu kod, albatta, ishlamaydi va biz uni oddiygina "bu qanday bo'lishi mumkin" misoli sifatida taqdim etamiz:
public class MysteriousDevice extends Toster, NuclearBomb {

   public static void main(String[] args) {

       MysteriousDevice mysteriousDevice = new MysteriousDevice();
       mysteriousDevice.on(); // And what should happen here? Will we get a toast, or a nuclear apocalypse?
   }
}
Keling, nima borligini ko'rib chiqaylik. Sirli qurilma tushdi mashinasidan ham, yadroviy bombadan ham keladi. Ikkalasida ham usul bor on()va natijada, agar biz uni chaqirsak, on()ob'ektga qaysi usulni yoqish kerakligi aniq emas. MysteriousDeviceOb'ekt buni tushuna olmaydi. Xo'sh, kekdagi gilos kabi: Yadro bombasining usuli yo'q off(), shuning uchun biz noto'g'ri taxmin qilgan bo'lsak, qurilmani o'chirishning hech qanday usuli bo'lmaydi. Aniq misollar bilan Java-da abstrakt sinflar - 2 Aynan shu chalkashlik tufayli, ob'ekt qaysi xatti-harakatni tanlashi kerakligi noma'lum bo'lsa, Java yaratuvchilari bir nechta merosdan voz kechishdi. Biroq, Java sinflari ko'plab interfeyslarni amalga oshirishini eslaysiz. Aytgancha, siz o'qishingizda kamida bitta abstrakt sinfga duch kelgansiz! Garchi men buni sezmagan bo'lsam ham :)
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>
Bu sizning eski do'stingiz - sinf Calendar. U mavhum va bir nechta merosxo'rlarga ega. Ulardan biri GregorianCalendar. Siz uni sanalar haqidagi darslarda allaqachon ishlatgansiz :) Hamma narsa aniq ko'rinadi, faqat bitta nuqta qoldi: mavhum sinflar va interfeyslar o'rtasidagi asosiy farq nima ? Nima uchun ular ikkalasini ham Java-ga qo'shdilar va faqat bittasi bilan cheklanmadilar? Bu etarli bo'lishi mumkin. Bu haqda keyingi ma'ruzada gaplashamiz! Ko'rishguncha:)
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION