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 .
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.
Car
Faqat 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();
}
}
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
Car
mavhum 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() {
}
public void brake() {
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car();
}
}
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();
}
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
Sedan
ikki qismga bo'lindi: agar siz unga usulni chaqirsangiz
gas()
, u ota-ona mavhum sinfdan "yuqoriga tortadi"
Car
va
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 -
Toster
va
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();
}
}
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.
MysteriousDevice
Ob'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.
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:)
GO TO FULL VERSION