JavaRush /Java Blogu /Random-AZ /Alıcılar və tənzimləyicilər

Alıcılar və tənzimləyicilər

Qrupda dərc edilmişdir
Salam! Əvvəlki mühazirələrdə siz artıq sahələr və üsullarla öz tam hüquqlu siniflərinizi necə yaratmağı öyrəndiniz. Bu ciddi irəliləyişdir, yaxşı! Amma indi sizə xoşagəlməz bir həqiqəti deməliyəm. Biz dərslərimizi düzgün qurmadıq! Niyə? İlk baxışdan bu sinifdə heç bir səhv yoxdur:
public class Cat {

   public String name;
   public int age;
   public int weight;

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

   public Cat() {
   }

   public void sayMeow() {
       System.out.println("Meow!");
   }
}
Əslində var. CatTəsəvvür edin ki, işdə oturarkən pişikləri ifadə edən belə bir sinif yazdınız . Və evə getdi. Siz uzaqda olanda başqa bir proqramçı işə gəldi, öz sinfini yaratdı Mainvə burada yazdığınız sinifdən istifadə etməyə başladı Cat.
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";
       cat.age = -1000;
       cat.weight = 0;
   }
}
Niyə bunu etdiyini və ya necə baş verdiyinin əhəmiyyəti yoxdur: bəlkə də insan yorğun idi və ya kifayət qədər yatmadı. Başqa bir şey vacibdir: cari sinifimiz Catsahələrə çılğın dəyərlər təyin etməyə imkan verir. Nəticədə, proqramda -1000 il yaşı olan bu pişik kimi yanlış vəziyyətə malik obyektlər var. Nə səhvə yol verdik? Biz sinfi yaradanda onun məlumatlarını ifşa etdik. Sahələr namevə ictimai mülkiyyətdədir age. weightOnlara proqramın istənilən yerindən daxil olmaq olar: sadəcə obyekt yaradın Cat- vəssalam, istənilən proqramçı onun məlumatlarına birbaşa “ .” operatoru vasitəsilə daxil ola bilər.
Cat cat = new Cat();
cat.name = "";
Burada birbaşa sahəyə daxil oluruq namevə onun dəyərini təyin edirik. Biz bir şəkildə məlumatlarımızı kənardan yanlış müdaxilələrdən qorumalıyıq. Bunun üçün nə lazımdır? Birincisi, bütün nümunə dəyişənləri (sahələr) dəyişdirici ilə qeyd edilməlidir private. Private Java-da ən sərt giriş dəyişdiricisidir. Onu istifadə etsəniz, sinif sahələrinə Catondan kənarda daxil olmaq mümkün olmayacaq.
public class Cat {

   private String name;
   private int age;
   private int weight;

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

   public Cat() {
   }

   public void sayMeow() {
       System.out.println("Meow!");
   }
}

public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";//error! The name field in the Cat class has private access!
   }
}
Kompilyator bunu görür və dərhal xəta yaradır. İndi əkin sahələri mühafizə olunur. Ancaq məlum oldu ki, onlara giriş "sıx" bağlıdır: proqram, lazım gələrsə, mövcud bir pişiyin çəkisini belə ala bilmir. Bu da bir seçim deyil: bu formada sinifimizdən istifadə etmək praktiki olaraq mümkün deyil. İdeal olaraq, məlumatlara bir növ məhdud girişə icazə verməliyik:
  • Digər proqramçılar obyektlər yaratmağı bacarmalıdırlarCat
  • Onlar artıq mövcud obyektlərdən məlumatları oxuya bilməlidirlər (məsələn, artıq mövcud olan pişiyin adını və ya yaşını əldə edin)
  • Sahə qiymətlərini təyin etmək də mümkün olmalıdır. Ancaq eyni zamanda - yalnız düzgün dəyərlər. Obyektlərimiz səhv olanlardan qorunmalıdır (“yaş = -1000 il” və s.).
Tələblərin siyahısı layiqdir! Ancaq əslində bütün bunlar xüsusi üsullardan istifadə etməklə asanlıqla əldə edilir - alıcılartənzimləyicilər .
Qəbul edənlər və təyin edənlər - 2
Ad ingilis dilindən " get " - " almaq " (yəni "sahənin dəyərini əldə etmək üsulu") və set - " set " (yəni "sahənin dəyərini təyin etmək üsulu") sözlərindən gəlir. Nümunə olaraq sinfimizdən istifadə edərək onların necə göründüyünə baxaq Cat:
public class Cat {

   private String name;
   private int age;
   private int weight;

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

   public Cat() {
   }

   public void sayMeow() {
       System.out.println("Meow!");
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public int getAge() {
       return age;
   }

   public void setAge(int age) {
       this.age = age;
   }

   public int getWeight() {
       return weight;
   }

   public void setWeight(int weight) {
       this.weight = weight;
   }
}
Gördüyünüz kimi, hər şey olduqca sadədir :) Onların adları ən çox get/set sözündən + məsul olduqları sahənin adından ibarətdir. Məsələn, metod çağırıldığı obyektin getWeight()sahə dəyərini qaytarır . weightProqramda belə görünür:
public class Main {

   public static void main(String[] args) {

       Cat barsik = new Cat("Barsik", 5, 4);
       String barsikName = barsik.getName();
       int barsikAge = barsik.getAge();
       int barsikWeight = barsik.getWeight();

       System.out.println("Cat name: " + barsikName);
       System.out.println("Cat's age: " + barsikAge);
       System.out.println("Weight of the cat: " + barsikWeight);
   }
}
Konsol çıxışı:

Name кота: Барсик
Возраст кота: 5
Вес кота: 4
İndi başqa sinifdən ( Main) sahələrə giriş var Cat, ancaq alıcılar vasitəsilə . Nəzərə alın ki, alıcıların giriş dəyişdiricisi var public, yəni onlara proqramın istənilən yerindən daxil olmaq mümkündür. Bəs dəyərlər təyin etmək? Setter metodları buna cavabdehdir
public void setName(String name) {
   this.name = name;
}
Onların işi də gördüyünüz kimi sadədir. setName()Biz obyektdə metodu çağırırıq Cat, onu arqument kimi sətirlə ötürürük və bu sətir nameobyektimizin sahəsinə təyin edilir.
public class Main {

   public static void main(String[] args) {

       Cat barsik = new Cat("Barsik", 5, 4);

       System.out.println("The original name of the cat is " + barsik.getName());
       barsik.setName("Basil");
       System.out.println("The new name of the cat -" + barsik.getName());
   }
}
Burada həm alıcılardan, həm də təyinedicilərdən istifadə etdik. Əvvəlcə alıcıdan istifadə edərək, pişiyin ilkin adını aldıq və konsola çıxardıq. Sonra, bir tənzimləyicidən istifadə edərək, nameonun sahəsinə yeni bir dəyər təyin edildi - "Vasili". Və sonra, alıcıdan istifadə edərək, həqiqətən dəyişib-dəyişmədiyini yoxlamaq üçün adı yenidən aldıq. Konsol çıxışı:

Изначальное Name кота — Барсик
Новое Name кота — Васorй
Görünür, fərq nədir? Ayarlayıcılarımız olsa belə, obyekt sahələrinə səhv dəyərlər təyin edə bilərik:
public class Main {

   public static void main(String[] args) {

       Cat barsik = new Cat("Barsik", 5, 4);
       barsik.setAge(-1000);

       System.out.println("Age of Barsik -" + barsik.getAge() + " years");
   }
}
Konsol çıxışı:

Возраст Барсика — -1000 лет
Fərq ondadır ki, setter tam hüquqlu bir üsuldur . Və bir metodda, bir sahədən fərqli olaraq, qəbuledilməz dəyərlərin qarşısını almaq üçün lazım olan yoxlama məntiqini qoya bilərsiniz. Məsələn, yaşa görə mənfi nömrə təyin etməyi asanlıqla söndürə bilərsiniz:
public void setAge(int age) {
   if (age >= 0) {
       this.age = age;
   } else {
       System.out.println("Error! Age cannot be negative!");
   }
}
İndi kodumuz düzgün işləyir!
public class Main {

   public static void main(String[] args) {

       Cat barsik = new Cat("Barsik", 5, 4);
       barsik.setAge(-1000);

       System.out.println("Age of Barsik -" + barsik.getAge() + " years");
   }
}
Konsol çıxışı:

Ошибка! Возраст не может быть отрицательным числом!
Возраст Барсика — 5 лет
Tənzimləyicinin daxilində məhdudiyyət var və o, yanlış məlumatları təyin etmək cəhdlərindən qoruyur. Barsikin yaşı dəyişməz qalıb. Alıcılar və tənzimləyicilər həmişə yaradılmalıdır. Sahələrinizdə mümkün dəyərlərə məhdudiyyət qoyulmasa belə, onlardan heç bir zərər olmayacaq. Vəziyyəti təsəvvür edin: siz və həmkarlarınız birlikdə proqram yazırsınız. Siz ictimai sahələri olan bir sinif yaratdınız Catvə bütün proqramçılar onlardan istədikləri kimi istifadə edirlər. Və sonra bir gözəl gün sizə belə gəlir: “Lənət olsun, gec-tez kimsə təsadüfən dəyişənə mənfi rəqəm təyin edə bilər weight! Biz tənzimləyicilər yaratmalı və bütün sahələri özəl etməliyik!” Siz onları yaradırsınız və həmkarlarınızın yazdığı bütün kodlar dərhal pozulur. Axı, onlar artıq sahələrə Catbirbaşa daxil olduqları bir dəstə kod yazmışdılar.
cat.name = "Hippopotamus";
İndi sahələr özəl oldu və tərtibçi çoxlu səhvlər yaradır!
cat.name = "Hippopotamus";//error! The name field of the Cat class has private access!
Belə bir vəziyyətdə, sahələri gizlətmək və ən başından alıcı-setter yaratmaq daha yaxşı olardı . Bütün həmkarlarınız onlardan istifadə edərdi və əgər gec başa düşsəniz ki, siz sahə dəyərlərini məhdudlaşdırmalısınız, sadəcə olaraq təyinedicinin içərisinə bir çek əlavə edərdiniz. Artıq yazılmış kodu heç kim pozmazdı. Əlbəttə ki, müəyyən bir sahəyə yalnız oxumaq üçün giriş əldə etmək istəyirsinizsə, bunun üçün bir alıcı yarada bilərsiniz. “Kənarda”, yəni sinifinizdən kənarda yalnız metodlar mövcud olmalıdır. Məlumatlar gizlədilməlidir.
Alıcılar və tənzimləyicilər - 4
Cib telefonu ilə bənzətmə etmək olar. Təsəvvür edin ki, işə salınmış adi cib telefonu əvəzinə sizə bütün naqillərin, sxemlərin və s. olduğu açıq korpuslu telefon verilib. yapışaraq. Telefon işləyir: çox çalışsanız və diaqramlarla məşğul olsanız, hətta zəng edə bilərsiniz. Ancaq çox güman ki, onu pozacaqsınız. Bunun əvəzinə, istehsal şirkəti sizə interfeys təqdim edir: müştəri sadəcə tələb olunan nömrələri yığır, telefonla yaşıl düyməni sıxır və zəng başlayır. O, dövrə və naqillərdə nə baş verdiyini və onların öz vəzifələrini necə yerinə yetirdiyini maraqlandırmır. Bu nümunədə şirkətin telefonun “daxili hissələrinə” (məlumatlarına) məhdud çıxışı var və yalnız interfeysi (metodları) kənarda qoyub. Nəticədə, müştəri istədiyini alacaq (zəng edəcək) və mütləq içəridə heç nə sındırmayacaq.
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION