Abstrakt sinflar
Abstrakt sinflardan foydalanishga cheklovlar
Download 89.02 Kb.
|
d 17
- Bu sahifa navigatsiya:
- Abstrakt sinflar
Abstrakt sinflardan foydalanishga cheklovlar.
Abstrakt sinflardan quyidagilar uchun foydalanish mumkin emas: a'zo o'zgaruvchilari va ma'lumotlari; argument turlari; funksiyalar tomonidan qaytariladigan qiymatlar turlari; aniq konvertatsiya turlari. Agar mavhum sinf konstruktori sof virtual funktsiyani bevosita yoki bilvosita chaqirsa, natija aniqlanmagan. Biroq, mavhum sinflarning konstruktorlari va destruktorlari boshqa a'zo funktsiyalarni chaqirishi mumkin. Abstrakt sinflar Abstrakt sinf - bu sinfdan hech qanday ob'ekt yaratib bo'lmaydi. Shu bilan birga, sinf merosxo'rlari mavhum bo'lmasligi mumkin, mos ravishda ular asosida ob'ektlar yaratilishi mumkin. Sinf abstraktini yaratish uchun uning nomidan oldin mavhum modifikatorni ko'rsatish kerak. Abstrakt A sinfining misolini ko'rib chiqing: mavhum sinf A { int p1 ; A () { p1 = 1 ; } bekor chop etish () { Tizim . tashqariga . println ( p1 ); } } B sinfini kengaytiradi A { } umumiy sinf Asosiy { umumiy statik void main ( String [] args ) { A ob1 ; // xato: ob1 = new A(); B ob2 = yangi B (); // A ob2 dan standart konstruktsiyalar chaqiriladi . chop etish (); } } Java konstruktorlarni A sinfida e'lon qilishga imkon beradi, lekin ulardan foydalanishga ruxsat bermaydi (chunki abstrakt sinf ob'ektlarini yaratish taqiqlanadi). E'tibor bering, ob1 o'zgaruvchisini A sinf ob'ektiga havola sifatida e'lon qilish ham taqiqlanmagan. Sinf kastingi Nima uchun ob1 havolasi talab qilinishi mumkin, u bilan qanday ob'ekt bog'lanishi mumkin? Masalan, B avlod sinfining ob'ekti. Gap shundaki, A sinf ota-ona sifatida B avlodiga qaraganda universalroqdir. Bu shuni anglatadiki, avlod sinfining har qanday ob'ekti aniq yoki hatto avtomatik ravishda o'zgartirilishi mumkin. ota-onalar sinfi. Ya'ni, asosiy usulning quyidagi mazmuni juda to'g'ri bo'ladi: A ob1 ; B ob2 = yangi B (); ob1 = ( A ) ob2 ; // aniq cast ob1 . chop etish (); Bundan tashqari, aktyorlar ham yashirin (avtomatik) bo'lishi mumkin: ob1 = ob2 ; // avtomatik quyish O'rnatilgan turlar va sinflar uchun, biz o'zgaruvchini yoki ob'ektni universalroq turga (butun sonlar haqiqiy sonlarga, B asosiy ob'ekt A sinfiga va boshqalar) o'tkazishga harakat qilganimizda, avtomatik quyish har doim mumkin. Abstrakt usullar Mavhum usul - bu berilgan sinfda amalga oshirilmaydigan usul. Uning argumentlari sanab o'tilgan qavslardan keyin usul deklaratsiyasi blokini boshlash uchun ochiladigan jingalak qavs emas, balki nuqta-vergul qo'yiladi. Ya'ni, mavhum usulning tavsifi yo'q. Bunda mavhum modifikator usul nomidan oldin ko'rsatiladi. Amalga oshirishsiz usul yaratishning nima keragi bor? Chunki undan foydalanish mumkin emas. Usul tavsiflangan sinf ob'ektlari uchun, albatta, undan foydalanish mumkin emas, lekin agar siz sinfni meros qilib olsangiz va u erda uning tavsifini ko'rsatgan holda avlodlardagi usulni bekor qilsangiz, u holda usulni avlod sinflari ob'ektlari uchun chaqirish mumkin. (va avlod sinflarida tasvirlangan ilovalar ishlaydi). Mavhum usuldan foydalanish imkoniyatini istisno qilish uchun Java quyidagi talabni kiritdi: kamida bitta abstrakt metodga ega bo'lgan sinf mavhum sinf bo'lishi kerak. Qachon mavhum usullar va sinflardan foydalanish maqsadga muvofiq? Avval mavhum sinflar yoki mavhum usullar mavjud bo'lmagan uy hayvonlari sinfi ierarxiyasi misolini ko'rib chiqaylik. class Pet { String nomi ; int yoshi ; boolean ochlik ; bekor ovoz () { } bekor ovqat () { och = yolg'on ; } } sinf Snake uzaytiradi Pet { double length ; bekor ovoz () { Tizim . tashqariga . println ( "shhhhh" ); } } sinf iti uzaytiradi Pet { void ovoz () { tizimi . tashqariga . println ( "woof-woof" ); } } sinf PatrolDog kengaytiradi Dog { bekor ovoz () { Tizim . tashqariga . println ( "rrrr" ); } } sinf Cat kengaytiradi Pet { bekor ovoz () { Tizim . tashqariga . println ( "Miyav-miyov" ); } } class Fish extensions Pet { } public class Main { public static void main ( String [] args ) { Pet zorka = new Pet (); zorka . oziq-ovqat (); Fish nemo = yangi baliq (); nemo . ovoz (); } } Barcha uy hayvonlari chiqaradigan umumiy tovush yo'qligi sababli, biz Pet sinfida ovoz () usulini amalga oshirishni o'rnatmadik, usul ichida hech narsa qilinmaydi, ammo shunga qaramay, uning tanasi jingalak qavslardan blok bilan ajratilgan. Voice() usuli mavhum bo'lish uchun yaxshi nomzoddir. Bundan tashqari, siz o'zingizga noaniq turdagi uy hayvonini olishingiz dargumon, ya'ni sizning uyingizda mushuk, it yoki hatto ilon yaxshi yashashi mumkin, ammo siz aniq bo'lmagan uy hayvonlarini olishingiz qiyin. JSSV. Shunga ko'ra, haqiqiy vazifa doirasida Pet sinfining ob'ektlarini yaratish kerak bo'lishi dargumon, ya'ni uni mavhum qilish mumkin (bundan keyin biz ob'ektlarni yarata olmaymiz. buni qilganda ham). Mavhum sinf va mavhum usulni o'z ichiga olgan misolni ko'rib chiqing: mavhum sinf Pet { String nomi ; int yoshi ; boolean ochlik ; mavhum bo'sh ovoz (); bekor ovqat () { och = yolg'on ; } } sinf Snake uzaytiradi Pet { double length ; bekor ovoz () { Tizim . tashqariga . println ( "shhhhh" ); } } sinf iti uzaytiradi Pet { void ovoz () { tizimi . tashqariga . println ( "woof-woof" ); } } sinf PatrolDog kengaytiradi Dog { bekor ovoz () { Tizim . tashqariga . println ( "rrrr" ); } } sinf Cat kengaytiradi Pet { bekor ovoz () { Tizim . tashqariga . println ( "Miyav-miyov" ); } } class Fish extensions Pet { void voice () { } } public class Main { public static void main ( String [] args ) { // xato: Pet zorka = new Pet(); Fish nemo = yangi baliq (); nemo . ovoz (); } } E'tibor bering, endi, birinchidan, biz Pet mavhum sinfi ob'ektlarini yarata olmaymiz, ikkinchidan, ovoz () usulini amalga oshirish mavhum sinflar bo'lmagan uning barcha avlodlarida (hech bo'lmaganda bo'sh amalga oshirish) mavjud bo'lishi kerak. Garchi biz mavhum bolani yaratishimiz mumkin: mavhum sinf Baliq uzaytiradi Pet { } Ammo agar biz Fish sinfining ob'ektlarini yarata olmasak, oxir-oqibat mavhum bo'lmagan ob'ektni olish va unga asoslangan ob'ektlarni yaratish uchun sinfni kengaytirishimiz kerak edi. Masalan: sinf GoldenFish Fish uzaytiradi { bekor ovoz () { } } Interfeyslar Interfeys Java dasturlash tili konstruksiyasi bo‘lib, unda faqat mavhum umumiy usullar va yakuniy statik xususiyatlar e’lon qilinishi mumkin. Ya'ni, xuddi mavhum sinflar asosidagi kabi, interfeyslar asosida ob'ektlarni yaratib bo'lmaydi. Bir interfeys boshqa interfeysdan meros bo'lishi mumkin. Sinflar interfeyslarni amalga oshirishi mumkin (ya'ni interfeysdan usullar ro'yxatini oladi va ularning har birini amalga oshirishni tavsiflaydi) va eng muhimi, bitta sinf bir vaqtning o'zida bir nechta interfeyslarni amalga oshirishi mumkin. Interfeys kalit so'zi interfeys tavsifidan oldin joylashtiriladi. Sinf interfeysni amalga oshirganda, uning nomidan so'ng amalga oshirish kalit so'zi keladi va keyin vergul bilan ajratilgan holda, sinfda usullari to'liq tavsiflanadigan interfeyslarning nomlari ro'yxatga olinadi. Misol:
interfeysi Instruments { final static String key = "C major" ; ommaviy bekor o'yin (); } sinf Baraban amalga oshiradi Instruments { public void play () { System . tashqariga . println ( "boom bang bang boom bang bang" ); } } sinf Gitara amalga oshiradi Instruments { public void play () { System . tashqariga
interfeysi Instruments { statik umumiy String key = "C major" ; bo'sh o'yin ( ); } Biroq, interfeysni amalga oshiradigan sinfda play() usuli tasvirlangan bo'lsa, u hali ham undan oldin ommaviy modifikator bilan aniq ko'rsatilishi kerak bo'ladi. Interfeyslarning ko'p merosxo'rligi Java bir nechta sinf merosini qo'llab-quvvatlamaydi. Buning sababi shundaki, bunday meros ba'zi muammolarni keltirib chiqaradi. Ko'pincha, "olmos shaklidagi" merosdan kelib chiqadigan noaniqliklar, agar "A" klassi boshqa ikkita "B" va "C" toifalarining merosxo'ri bo'lsa, ular o'z navbatida ikkalasi ham merosxo'rlar bo'lsa, ko'rsatiladi. "D" toifasi. Ko'p merosni qabul qilish muammosi quyidagilardan iborat. Faraz qilaylik, m1() usuli A ota-onasida aniqlangan. Va biz D sinf ob'ekti uchun xuddi shu usulni chaqiramiz. Lekin agar m1() B va C sinflarida qayta aniqlangan bo'lsa-chi. D sinf ob'ekti uchun m1() usulini chaqirganda uchtasining qaysi amalga oshirishi ishlaydi? Noaniqlikni, ta'riflangan holatda, qo'ng'iroq qilishda, qo'ng'iroq qilishda qanday usullar talab qilinishini talab qilish orqali yo'q qilish mumkin (bu ba'zi tillarda amalga oshiriladi), ammo Java-da ular sinflarning ko'p merosidan voz kechishga qaror qilishdi. Sinflarning ko'p merosxo'rligi o'rniga Java interfeyslarning bir nechta merosini joriy qildi, bu muammolarni qisman hal qiladi (lekin quyidagi misolda ko'rsatilgandek, afsuski, hammasi emas). Yuk mashinalari va avtomobillar uchun mavjud usullar bilan ikkita interfeys amalga oshirilgan misolni ko'rib chiqing. Pikap klassi (pikap yuk mashinasi) yuk va yo'lovchilarni tashish qobiliyatiga ega bo'lishi kerak, shuning uchun u ikkala interfeysni bir vaqtning o'zida amalga oshiradi: interfeysi PassangersAuto { void transportPassangers (); } interfeysi CargoAuto { bekor transportCargo (); } sinf yuk mashinasi CargoAuto ni amalga oshiradi { final static int a = 1 ; jamoat bekor transportCargo () { tizimi . tashqariga . println ( "Men yuk ko'taryapman" ); } } klassi Sedan PassangersAuto { ommaviy amalga oshiradi void transportPassangers () { Tizim . tashqariga . println ( "Men yo'lovchilarni olib ketyapman" ); } } sinf Pikap CargoAuto , PassangersAuto { jamoat void transportCargo () { Tizimi amalga oshiradi . tashqariga . println ( "Men yuk ko'taryapman" ); } public void transportPassangers () { Tizim . tashqariga . println ( "Men yo'lovchilarni olib ketyapman" ); } }
Lekin interfeyslar, yuqorida aytib o'tilganidek, hech qanday kamchiliklarsiz mukammal vosita emas. Misolni ko'rib chiqing, bizda ikkita interfeys mavjud bo'lib, ularning har biri bir xil nomga ega xususiyatlarga ega (lekin, ehtimol, turli qiymatlar) va bir xil nomdagi usullar. Ushbu interfeyslarning juftligidan sinfni meros qilib olganimizdan so'ng, biz ikkita interfeysdan qaysi birini nazarda tutganimizni ko'rsatmasdan turib, uning ob'ektlari xususiyatiga to'g'ridan-to'g'ri kira olmaymiz. Ushbu cheklov mavjud, chunki interfeyslarda xususiyatlarga turli xil boshlang'ich qiymatlar berilishi mumkin va shunga mos ravishda dastur qaysi qiymatni tanlashni aniqlay olmaydi. Xususiyatga interfeyslardan birining statik xususiyati sifatida ham murojaat qilishingiz mumkin (albatta, bu xususiyatlar turli nomlarga ega bo'lsa ham amalga oshirilishi mumkin). Agar xususiyatga kirishdan oldin biz ob'ektni asosiy interfeyslardan biriga o'tkazsak, muammo yo'qoladi (esda tutingki, har qanday ob'ekt uning to'g'ridan-to'g'ri yoki o'tishli ota-onasining sinfiga yoki interfeysiga aniq uzatilishi mumkin). Afsuski, merosxo'r sinfidagi turli xil interfeyslardan bir xil nomdagi ikkita usul uchun alohida ilovalarni yaratish ishlamaydi (shunda ular keyinchalik kerakli interfeysga ob'ektlarni bir xil quyish orqali ishlatilishi mumkin). Agar sinf bir xil nomdagi usullarga ega bo'lgan bir nechta interfeyslarni amalga oshirsa, unda ushbu usullarning faqat bitta umumiy amalga oshirilishi ko'rsatilishi mumkin (va bu allaqachon Java interfeyslari orqali ko'p merosli polimorfizmni cheklaydi). Download 89.02 Kb. Do'stlaringiz bilan baham: |
ma'muriyatiga murojaat qiling