JavaRush /Java блогу /Random-KY /Алуучу жана орнотуучулар

Алуучу жана орнотуучулар

Группада жарыяланган
Салам! Мурунку лекцияларда сиз өзүңүздүн толук кандуу класстарыңызды, тармактары жана ыкмалары менен кантип түзүүнү үйрөндүңүз. Бул олуттуу прогресс, молодец! Бирок азыр бир жагымсыз чындыкты айтууга туура келет. Биз класстарыбызды туура түзгөн жокпуз! Неге? Биринчи караганда, бул класста каталар жок:
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талааларга жинди маанилерди дайындоого мүмкүндүк берет. Натыйжада, программа туура эмес абалы менен an objectтерди камтыйт, мисалы, бул мышык жашы -1000 жыл. Кандай ката кетирдик? Классты түзгөнүбүздө анын маалыматтарын ачыкка чыгардык. Талаалар nameжана коомдук доменде age. weightАларга программанын каалаган жеринен кирүүгө болот: жөн гана an object түзүңүз Cat- бүттү, каалаган программист анын маалыматтарына түздөн-түз “ .” оператору аркылуу кире алат.
Cat cat = new Cat();
cat.name = "";
Бул жерде биз талаага түздөн-түз кирип name, анын маанисин белгилейбиз. Биз кандайдыр бир жол менен маалыматыбызды сырттан туура эмес кийлигишүүдөн коргошубуз керек. Бул үчүн эмне керек? Биринчиден, бардык инстанция өзгөрмөлөрү (талаалар) өзгөрткүч менен белгилениши керек private. Private - бул Javaдагы эң катаал мүмкүндүк өзгөртүүчүсү. Эгер сиз аны колдонсоңуз, класстын талаалары Catанын сыртында жеткorктүү болбойт.
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!
   }
}
Компилятор муну көрүп, дароо ката чыгарат. Азыр талаалар корголгондой. Бирок, аларга кирүү "тыкан" жабык экени көрүнүп турат: программа керек болсо, учурдагы мышыктын салмагын да ала алbyte. Бул да вариант эмес: бул формада биздин классты колдонуу дээрлик мүмкүн эмес. Идеалында биз маалыматтарга кандайдыр бир чектелген мүмкүнчүлүккө уруксат беришибиз керек:
  • Башка программисттер an objectтерди түзө алышы керекCat
  • Алар мурунтан эле бар an objectтерден маалыматтарды окуй алышы керек (мисалы, мурунтан эле бар мышыктын атын же жашын алуу)
  • Ошондой эле талаа маанилерин дайындоо мүмкүн болушу керек. Бирок, ошол эле учурда - бир гана туура баалуулуктар. Биздин an objectилер туура эмес нерселерден корголушу керек (жок "жашы = -1000 жыл" жана ушул сыяктуу).
талаптардын тизмеси татыктуу! Бирок, чындыгында, мунун баарына атайын ыкмаларды колдонуу менен оңой жетүүгө болот - getters and setters .
Алуучулар жана орнотуучулар - 2
Аталышы англис тorнен келип чыккан “ алуу ” - “ алуу ” (б.а. “талаанын маанисин алуу ыкмасы”) жана коюлган – “ 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;
   }
}
Көрүнүп тургандай, баары абдан жөнөкөй :) Алардын аттары көбүнчө алуу/коюу деген сөздөн + алар жооптуу болгон талаанын аталышынан турат. Мисалы, метод ал чакырылган an objectтин 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, башкача айтканда, алар программанын каалаган жеринен жеткorктүү. баалуулуктарды дайындоо жөнүндө эмне айтууга болот? Бул үчүн Setter ыкмалары жооптуу
public void setName(String name) {
   this.name = name;
}
Алардын иши, сиз көрүп тургандай, да жөнөкөй. setName()Биз an objectтеги методду чакырабыз , аны аргумент катары сапка өткөрүп беребиз жана бул сап биздин an objectибиздин 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 лет
Айырмачылыгы сетер толук кандуу ыкмасы болуп саналат . Ал эми ыкмада, талаадан айырмаланып, сиз кабыл алынгыс маанилердин алдын алуу үчүн керектүү текшерүү логикасын киргизе аласыз. Мисалы, сиз курак боюнча терс санды ыйгарууну оңой эле өчүрө аласыз:
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дун баары ошол замат бузулат. Анткени, алар талааларга Catтүздөн-түз кире турган бир топ codeду жазышкан.
cat.name = "Hippopotamus";
Эми талаалар жеке болуп калды жана компилятор бир топ каталарды чыгарат!
cat.name = "Hippopotamus";//error! The name field of the Cat class has private access!
Мындай кырдаалда талааларды жашырып, башынан эле гетер-сетерлерди түзүү жакшы болмок . Сиздин бардык кесиптештериңиз аларды колдонушат жана эгер сиз талаанын маанилерин чектөө керек экениңизди кеч түшүнсөңүз, жөн гана орнотуучунун ичине чекти кошосуз. Ал эми буга чейин жазылган codeду эч ким бузмак эмес. Албетте, эгер сиз белгилүү бир талаага окуу үчүн гана кирүүнү кааласаңыз, анда ал үчүн бир алуучу түзө аласыз. "Сырттан", башкача айтканда, классыңыздан тышкары, методдор гана жеткorктүү болушу керек. Маалыматтар жашырылышы керек.
Алуучулар жана орнотуучулар - 4
Аналогияны уюлдук телефон менен жасоого болот. Элестетиңиз, күйгүзүлгөн кадимки уюлдук телефондун ордуна сизге бардык зымдары, схемалары ж. чыгып калуу. Телефон иштейт: эгер сиз аракет кылып, диаграммалар менен скрипка кылсаңыз, чалуу да жасай аласыз. Бирок, балким, жөн эле сындырып аласыз. Анын ордуна өндүрүшчү компания сизге интерфейсти берет: кардар жөн гана керектүү номерлерди терет, телефон телефону менен жашыл баскычты басып, чалуу башталат. Ал чынжырлар жана зымдар менен ичинде эмне болуп жатканын жана алар өз милдетин кантип аткарып жатканына маани бербейт. Бул мисалда компаниянын телефондун "ичкилерине" (маалыматтарына) кирүү мүмкүнчүлүгү чектелген жана сыртында интерфейсти (ыкмаларды) гана калтырган. Натыйжада, кардар каалаган нерсесин алат (чалуу) жана сөзсүз ичинде эч нерсе сындырbyte.
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION