1. O'zgaruvchilarni initsializatsiyasi
Siz allaqachon bilasizki, sinfingizda bir nechta sinf o'zgaruvchilarini e'lon qilishingiz mumkin, va nafaqat e'lon qilasiz, balki ularga boshlang'ich qiymatlarni ham tayinlaysiz.
Lekin bu o'sha o'zgaruvchilarni konstruktor ichida ham initsializatsiya qilish mumkin. Natijada, nazariy jihatdan shunday holat bo'lishi mumkin: sinf o'zgaruvchilariga bir xil qiymatlar ikki marta tayinlanadi. Misol:
| Kod | Izoh |
|---|---|
|
O'zgaruvchi age ga boshlang'ich qiymat berilgan Boshlang'ich qiymat o'zgartirilgan age uchun boshlang'ich qiymat ishlatiladi |
|
Bu mumkin: birinchi konstruktor chaqiriladi |
|
Bu mumkin: ikkinchi konstruktor chaqiriladi |
Mana bu kod ishlayotgan paytda nima bo'ladi Cat cat = new Cat("Vasyka", 2);:
Catturidagi obyekt yaratiladi- Sinfdagi barcha o'zgaruvchilar boshlang'ich qiymatlari bilan initsializatsiya qilinadi
- Konstruktor chaqiriladi va uning kodi bajariladi.
Ya'ni, sinf o'zgaruvchilari avval o'z qiymatlari bilan initsializatsiya qilinadi va shundan keyin konstruktorlar kodi bajariladi.
2. Sinf o'zgaruvchilarini initsializatsiya qilish tartibi
O'zgaruvchilar shunchaki konstruktor ishidan oldin initsializatsiya qilinmaydi: ular aniq belgilangan tartibda — sinfdagi e'lon qilish tartibida initsializatsiya qilinadi.
Keling, mana shunday qiziqarli kodni ko'rib chiqaylik:
| Kod | Izoh |
|---|---|
|
Bunday kod kompilyatsiyalanmaydi, chunki a o'zgaruvchisi yaratilgan paytda, b va c o'zgaruvchilari hali yo'q. Mana bu tarzda yozishingiz mumkin, va bu kod ajoyib kompilyatsiyalanadi va ishlaydi.
| Kod | Izoh |
|---|---|
|
0 0+2 0+2+3 |
Izoh: lekin siz kodingiz boshqa dasturchilar uchun ochiq bo'lishi kerakligini eslaysiz, shuning uchun bunday usullarni ishlatmaslikka harakat qiling — bu kodni o'qishni qiyinlashtiradi.
Bu yerda shuni eslatib o'tish kerakki, sinf o'zgaruvchilari ularga qiymat tayinlanmasdan oldin standart qiymatga ega. int turi uchun bu nol.
JVM a o'zgaruvchisini initsializatsiya qilayotgan paytda, shunchaki unga int uchun standart qiymatni — 0 ni tayinlaydi.
b navbati kelganida, a o'zgaruvchisi allaqachon ma'lum va qiymatni o'z ichiga oladi, shuning uchun JVM unga 2 ni tayinlaydi.
Va c o'zgaruvchisi navbati kelganda, a va b o'zgaruvchilari allaqachon initsializatsiya qilingan, va JVM c uchun boshlang'ich qiymatni osongina hisoblaydi: 0+2+3.
Agar siz metod ichida o'zgaruvchi yaratsangiz, unga qandaydir qiymat tayinlamasdan uni ishlata olmaysiz. Lekin sinf o'zgaruvchilari bilan bunday emas. Sinf o'zgaruvchisiga boshlang'ich qiymat berilmagan bo'lsa, unga standart qiymat tayinlanadi.
3. Konstantalar
Agar biz obyekt yaratish jarayonini davom ettirsak, sinf o'zgaruvchilariga final modifikatori bilan tayinlangan konstantalarni ham ko'rib chiqishimiz kerak.
Agar sinf o'zgaruvchisi final modifikatori bo'lsa, unga boshlang'ich qiymat tayinlanishi kerak. Bu siz allaqachon bilasiz, va bunda hech qanday ajabtovur narsa yo'q.
Lekin siz bilmagan narsa shundaki, boshlang'ich qiymatni darhol tayinlash shart emas, agar uni konstruktor ichida tayinlasangiz. Bu final o'zgaruvchi uchun ajoyib ishlaydi. Yagona talab - agar bir nechta konstruktor bo'lsa, barcha konstruktorlar ichida final o'zgaruvchiga qiymat tayinlanishi kerak.
Misol:
public class Cat
{
public final int maxAge = 25;
public final int maxWeight;
public Cat (int weight)
{
this.maxWeight = weight; // konstantaga boshlang'ich qiymatni tayinlash
}
}
4. Konstruktor ichidagi kod
Konstruktorlar masalasida yana bir nechta muhim eslatma. Kelajakda, Java o'rganish jarayonida siz joylashtirish, seriyalizatsiya, istisnolar kabi narsalar bilan duch kelasiz. Ularning barchasi konstruktor ishiga turli darajada ta'sir qiladi. Hozir bu mavzularni chuqur o'rganishning ma'nosi yo'q, lekin hech bo'lmaganda ularga tegib o'tish kerak.
Masalan, konstruktorlar haqida bir muhim eslatma. Teoretik jihatdan konstruktor ichida istalgan qiyinchilikdagi kodni yozish mumkin. Lekin bunday qilish kerak emas. Misol:
|
Faylni o'qish oqimini ochamiz Faylni bayt massiviga o'qiymiz Bayt massivini matn shaklida saqlaymiz Fayl tarkibini ekranga chiqaramiz |
FilePrinter sinfi konstruktorida biz darhol faylga bayt oqimini ochdik va uning tarkibini o'qidik. Bu yetarli darajada murakkab xatti-harakat bo'lib, xatolikka olib kelishi mumkin.
Agar bunday fayl bo'lmasa, nima bo'ladi? Agar uni o'qishda muammolar bo'lsa-chi? Agar u juda katta bo'lsa-chi?
Murakkab mantiq xatoliklar ehtimolini oshiradi va kodni to'g'ri ishlov berishni talab qiladi.
Misol 1 – Seriyalizatsiya
Standart Java dasturida juda ko'p vaziyatlar bor, qachonki, sinfingiz obyektlari siz tomonidan yaratilmaydi. Misol uchun, siz obyektni tarmoq orqali jo'natishga qaror qildingiz: bu holda Java mashinasi o'z obyektni bayt to'plamiga aylantiradi, uni jo'natadi va yana qayta bayt to'plamidan obyektni yaratadi.
Va mana shu yerda, boshqa kompyuterda sizning faylingiz yo'qligi ma'lum bo'ladi, konstruktor ichida xato yuzaga keladi, va hech kim uni ishlov bera olmadi — bu esa dastur yopilishiga olib keladi.
Misol 2 — Sinf o'zgaruvchilarini initsializatsiyasi
Agar sinf konstruktoringiz checked-istisnolarni chiqarishi mumkin bo'lsa — throws kalit so'zini o'z ichiga oladi, siz ushbu istisnoni obyektni yaratuvchi metodda ushlashingiz kerak.
Agar bu metod bo'lmasa-chi? Misol:
| Kod | Izoh |
|---|---|
|
Bunday kod kompilyatsiyalanmaydi. |
FilePrinter sinfi konstruktori checked-istisnolarni o'z ichiga oladi: siz FilePrinter obyektini yaratishingiz mumkin emas, agar uni try-catch ichiga joylashtirmasdan. Va try-catch faqat metod ichida yozilishi mumkin
5. Baza sinfi konstruktori
Oldingi ma'ruzalarda biz vorislikni biroz muhokama qildik. Afsuski, vorislik va OOPni to'liq darajada biz OOPga ajratilgan darajada muhokama qilamiz, ammo bu konstruktorga allaqachon bog'liq.
Agar siz o'z sinfingizni boshqa sinfdan meros olsangiz, aslida sizning sinf obyektlaringiz ichiga ota-sinf obyekti joylashadi. Bundan tashqari, bu ota-sinf o'z sinf o'zgaruvchilari va o'z konstruktoriga ega.
Shuning uchun sizga va sizning vorislikka ega bo'lgan sinfingiz uchun o'zgaruvchilar va konstruktorlar qanday initsializatsiya qilinishini bilib olishingiz juda muhim.
Sinf
Biz qanday qilib o'zgaruvchilar initsializatsiya qilinishini va konstruktorlar qanday chaqirilishini qanday aniqlash mumkin? Keling, avval ikkita sinf kodini yozaylik, biri boshqasidan meros oladi:
| Kod | Izoh |
|---|---|
|
Sinf ChildClass ParentClass sinfdan meros oladi. |
Biz qanday qilib o'zgaruvchilar initsializatsiya qilinish tartibini va konstruktorlar chaqirilishini aniqlashimiz kerak. Buni loglash yordamida aniqlashimiz mumkin.
Loglash
Loglash dastur ish paytida sodir bo'layotgan harakatlarni konsol yoki faylga yozib olishdir.
Konstruktor chaqirilganini aniqlash juda oson: konstruktor ichida bu haqda konsolga xabar yozish kerak. Ammo o'zgaruvchining initsializatsiya qilinganini qanday aniqlash mumkin?
Aslida bu ham juda qiyin emas: sinf o'zgaruvchini initsializatsiya qilinadigan qiymatni qaytadigan va bu faktni loglaydigan maxsus metod yozish kerak. Mana bu kod qanday ko'rinishi mumkin:
Final kod
|
ChildClass turidagi obyekt yaratamiz Bu metod kiruvchi matnni konsolga yozadi va uni qaytaradi ParentClass ni e'lon qilamizMatnni yozamiz va shu bilan o'zgaruvchilarni initsializatsiya qilamiz Konstruktor chaqirilganligini konsolga yozamiz. Qaytadigan qiymatni hisobga olmaymiz. ChildClass ni e'lon qilamizMatnni yozamiz va shu bilan o'zgaruvchilarni initsializatsiya qilamiz Konstruktor chaqirilganligini konsolga yozamiz. Qaytadigan qiymatni hisobga olmaymiz. |
Agar bu kodni ishga tushirsangiz, ekranda quyidagi matn paydo bo'ladi:
Main.print() metodi konsol chiqishi |
|---|
|
Shunday ekan, sinf o'zgaruvchilari konstruktor chaqirilishidan oldin initsializatsiya qilinishiga o'zingizni ishontirishingiz mumkin. Baza sinfning barcha initsializatsiyasi vorislik sinfi initsializatsiyasidan oldin amalga oshiriladi.
GO TO FULL VERSION