Initsializatsiya

All lectures for UZ purposes
Daraja, Dars
Mavjud

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
class Cat
{
   public String name;
   public int age = -1;

   public Cat(String name, int age)
   {
     this.name = name;
     this.age = age;
   }

   public Cat()
   {
     this.name = "Ismsiz";
   }
}



O'zgaruvchi age ga boshlang'ich qiymat berilgan




Boshlang'ich qiymat o'zgartirilgan


age uchun boshlang'ich qiymat ishlatiladi
 Cat cat = new Cat("Vasyka", 2);
Bu mumkin: birinchi konstruktor chaqiriladi
 Cat cat = new Cat();
Bu mumkin: ikkinchi konstruktor chaqiriladi

Mana bu kod ishlayotgan paytda nima bo'ladi Cat cat = new Cat("Vasyka", 2);:

  • Cat turidagi 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
public class Solution
{
   public int a = b + c + 1;
   public int b = a + c + 2;
   public int c = a + b + 3;
}

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
public class Solution
{
   public int a;
   public int b = a + 2;
   public int c = a + b + 3;
}


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:

class FilePrinter
{
   public String content;

   public FilePrinter(String filename) throws Exception
   {
      FileInputStream input = new FileInputStream(filename);
      byte[] buffer = input.readAllBytes();
      this.content = new String(buffer);
   }

   public void printFile()
   {
      System.out.println(content);
   }
}






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
class Solution
{
   public FilePrinter reader = new FilePrinter("c:\\readme.txt");
}
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
class ParentClass
{ 
   public String a;
   public String b;

   public ParentClass()
   {
   }
}

class ChildClass extends ParentClass
{
   public String c;
   public String d;

   public ChildClass()
   {
   }
}










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

public class Main
{
   public static void main(String[] args)
   {
      ChildClass obj = new ChildClass();
   }

   public static String print(String text)
   {
      System.out.println(text);
      return text;
   }
}

class ParentClass
{
   public String a = Main.print("ParentClass.a");
   public String b = Main.print("ParentClass.b");

   public ParentClass()
   {
      Main.print("ParentClass.constructor");
   }
}

class ChildClass extends ParentClass
{
   public String c = Main.print("ChildClass.c");
   public String d = Main.print("ChildClass.d");

   public ChildClass()
   {
      Main.print("ChildClass.constructor");
   }
}




ChildClass turidagi obyekt yaratamiz


Bu metod kiruvchi matnni konsolga yozadi va uni qaytaradi





ParentClass ni e'lon qilamiz

Matnni yozamiz va shu bilan o'zgaruvchilarni initsializatsiya qilamiz




Konstruktor chaqirilganligini konsolga yozamiz. Qaytadigan qiymatni hisobga olmaymiz.


ChildClass ni e'lon qilamiz

Matnni 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
ParentClass.a ParentClass.b ParentClass.constructor
ChildClass.c ChildClass.d ChildClass.constructor

Shunday ekan, sinf o'zgaruvchilari konstruktor chaqirilishidan oldin initsializatsiya qilinishiga o'zingizni ishontirishingiz mumkin. Baza sinfning barcha initsializatsiyasi vorislik sinfi initsializatsiyasidan oldin amalga oshiriladi.


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