JavaRush /Java блогы /Random-KK /Алғыштар мен орнатушылар

Алғыштар мен орнатушылар

Топта жарияланған
Сәлеметсіз бе! Алдыңғы дәрістерде сіз өрістер мен әдістермен өзіңіздің толыққанды сыныптарыңызды құруды үйрендіңіз. Бұл маңызды прогресс, жақсы! Бірақ қазір мен сізге бір жағымсыз шындықты айтуым керек. Біз сабақтарымызды дұрыс құрмадық! Неліктен? Бір қарағанда, бұл сыныпта қателер жоқ:
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!");
   }
}
Шын мәнінде, бар. Жұмыста отырғанда сіз Catмысықтарды бейнелейтін сынып жаздыңыз деп елестетіңіз. Ал ол үйіне кетті. Сіз жоқ кезде басқа программист жұмысқа келді, өз класын құрды Main, онда ол сіз жазған классты қолдана бастады Cat.
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";
       cat.age = -1000;
       cat.weight = 0;
   }
}
Неліктен мұны істегені немесе бұл қалай болғаны маңызды емес: адам шаршаған немесе жеткілікті ұйықтамаған болуы мүмкін. Тағы бір маңызды нәрсе: біздің қазіргі класс Catөрістерге ақылсыз мәндерді тағайындауға мүмкіндік береді. Нәтижесінде бағдарламада қате күйі бар нысандар бар, мысалы, жасы -1000 жыл. Біз қандай қателік жасадық? Біз сыныпты жасаған кезде оның деректерін аштық. Өрістер name, ageжәне weightжалпыға ортақ доменде. Оларға бағдарламаның кез келген жерінен қол жеткізуге болады: жай ғана an object жасаңыз Cat- және міне, кез келген бағдарламашы оның деректеріне тікелей « .» операторы арқылы қол жеткізе алады.
Cat cat = new Cat();
cat.name = "";
Мұнда біз өріске тікелей кіріп name, оның мәнін орнатамыз. Бізге қандай да бір жолмен деректерімізді сыртқы кедергілерден қорғау керек. Бұл үшін не қажет? Біріншіден, барлық айнымалы айнымалылар (өрістер) модификатормен белгіленуі керек private. Private - Java-дағы ең қатал рұқсат модификаторы. Оны пайдалансаңыз, сыныптың өрістеріне 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 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!
   }
}
Компилятор мұны көреді және бірден қате шығарады. Қазір егістік алқаптар қорғалған көрінеді. Бірақ оларға қол жеткізу «тығыз» жабық екені белгілі болды: бағдарлама қажет болса, бар мысықтың салмағын да ала алмайды. Бұл да нұсқа емес: бұл формада біздің сыныпты пайдалану іс жүзінде мүмкін емес. Ең дұрысы деректерге қандай да бір шектеулі қол жеткізуге рұқсат беруіміз керек:
  • Басқа бағдарламашылар an objectілерді жасай алуы керекCat
  • Олар бұрыннан бар нысандардан деректерді оқи алуы керек (мысалы, бұрыннан бар мысықтың атын немесе жасын алу)
  • Сондай-ақ өріс мәндерін тағайындау мүмкіндігі болуы керек. Бірақ сонымен бірге - тек дұрыс мәндер. Біздің нысандар дұрыс емес нәрселерден қорғалуы керек («жасы = -1000 жыл» және т.б.).
Талаптар тізімі лайықты! Бірақ шын мәнінде, мұның бәріне арнайы әдістерді қолдану арқылы оңай қол жеткізуге болады - getters and setters .
Алғыштар мен орнатушылар – 2
Атау ағылшын тілінен « get » - « receive » (яғни, «өріс мәнін алу әдісі») және set - « set » (яғни, «өріс мәнін орнату әдісі») сөздерінен шыққан. Мысал ретінде біздің сыныпты қолданып, олардың қалай көрінетінін көрейік 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;
   }
}
Көріп отырғаныңыздай, бәрі өте қарапайым :) Олардың атаулары көбінесе get/set сөзінен + өздері жауапты болатын өрістің атынан тұрады. Мысалы, әдіс өзі шақырылған нысанның getWeight()өріс мәнін қайтарады . weightБұл бағдарламада келесідей көрінеді:
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);
   }
}
Консоль шығысы:

Name кота: Барсик
Возраст кота: 5
Вес кота: 4
Енді басқа сыныптан ( Main) өрістерге рұқсат бар Cat, бірақ тек алғыштар арқылы . Қабылдаушылардың кіру модификаторы бар екенін ескеріңіз public, яғни олар бағдарламаның кез келген жерінен қол жетімді. Мәндерді тағайындау туралы не деуге болады? Сетер әдістері бұған жауапты
public void setName(String name) {
   this.name = name;
}
Олардың жұмысы, өздеріңіз көріп отырғандай, қарапайым. setName()Біз нысандағы әдісті шақырамыз , оны аргумент ретінде жолды береміз және бұл жол нысанымыздың Catөрісіне тағайындалады .name
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());
   }
}
Мұнда біз алушыларды да, орнатушыларды да қолдандық. Біріншіден, гетер көмегімен біз мысықтың бастапқы атын алып, консольге шығардық. Содан кейін орнатушының көмегімен nameоның өрісіне жаңа мән тағайындалды - «Васorй». Содан кейін гетер арқылы біз оның шынымен өзгергенін тексеру үшін қайтадан атауды алдық. Консоль шығысы:

Изначальное Name кота — Барсик
Новое Name кота — Васorй
Көрінетін сияқты, айырмашылығы неде? Бізде орнатушылар болса да, an object өрістеріне қате мәндерді тағайындай аламыз:
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");
   }
}
Консоль шығысы:

Возраст Барсика — -1000 лет
Айырмашылығы - сетер - бұл толыққанды әдіс . Және әдіске, өріске қарағанда, қабылданbyteын мәндердің алдын алу үшін қажет тексеру логикасын қосуға болады. Мысалы, теріс санды жас бойынша тағайындауды оңай өшіруге болады:
public void setAge(int age) {
   if (age >= 0) {
       this.age = age;
   } else {
       System.out.println("Error! Age cannot be negative!");
   }
}
Енді біздің code дұрыс жұмыс істейді!
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");
   }
}
Консоль шығысы:

Ошибка! Возраст не может быть отрицательным числом!
Возраст Барсика — 5 лет
Орнатқыштың ішінде шектеу бар және ол қате деректерді орнату әрекеттерінен қорғайды. Барсиктің жасы өзгеріссіз қалды. Қабылдағыштар мен орнатушылар әрқашан жасалуы керек. Егер өрістеріңізде мүмкін мәндерге шектеулер болмаса да, олардан ешқандай зиян болмайды. Жағдайды елестетіп көріңіз: сіз және сіздің әріптестеріңіз бірге бағдарлама жазасыз. Сіз жалпы өрістері бар класс жасадыңыз Catжәне барлық бағдарламашылар оларды қалағандай пайдаланады. Содан кейін бір жақсы күн сізге таң қалады: «Қарғыс атсын, ерте ме, кеш пе біреу кездейсоқ айнымалыға теріс сан тағайындауы мүмкін weight! Біз орнатушыларды жасап, барлық өрістерді жеке етуіміз керек!» Сіз оларды жасайсыз және әріптестеріңіз жазған барлық code бірден бұзылады. Өйткені, олар өрістерге тікелей кіретін көптеген codeтар жазып қойған Cat.
cat.name = "Hippopotamus";
Енді өрістер жеке болды және компилятор көптеген қателер шығарады!
cat.name = "Hippopotamus";//error! The name field of the Cat class has private access!
Мұндай жағдайда өрістерді жасырып, басынан бастап гетер-сеттерді жасаған дұрыс болар еді . Сіздің барлық әріптестеріңіз оларды пайдаланады және өріс мәндерін шектеу қажет екенін кеш түсінсеңіз, орнатушының ішіне чекті қосасыз. Ал қазірдің өзінде жазылған codeты ешкім бұзбайды. Әрине, егер сіз белгілі бір өріске тек оқуға рұқсат алғыңыз келсе, ол үшін бір қабылдаушы жасай аласыз. «Сыртта», яғни сыныптан тыс жерде тек әдістер қолжетімді болуы керек. Деректер жасырын болуы керек.
Алғыштар мен орнатушылар - 4
Ұялы телефонмен ұқсастық жасауға болады. Елестетіп көріңізші, қосылған кәдімгі ұялы телефонның орнына сізге барлық сымдар, тізбектер және т.б. орналасқан ашық корпусы бар телефон берілді. шығып тұру. Телефон жұмыс істейді: егер сіз диаграммалармен скрипкамен айналысып, тырыссаңыз, сіз тіпті қоңырау шала аласыз. Бірақ сіз оны бұзатын шығарсыз. Оның орнына, өндіруші компания сізге интерфейс береді: клиент қажетті нөмірлерді теріп, телефон тұтқасымен жасыл түймені басып, қоңырау басталады. Оған тізбектер мен сымдар ішінде не болып жатқаны және олардың өз міндеттерін қалай орындайтыны маңызды емес. Бұл мысалда компанияның телефонның «ішкі бөліктеріне» (деректеріне) қол жеткізуі шектеулі және тек интерфейсті (әдістерді) сыртында қалдырды. Нәтижесінде, клиент қалаған нәрсені алады (қоңырау шалыңыз) және ішіндегі ештеңені бұзбайды.
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION