JavaRush /Java Blog /Random-TL /Getters at setter

Getters at setter

Nai-publish sa grupo
Kamusta! Sa nakaraang mga lektura, natutunan mo na kung paano lumikha ng iyong sariling ganap na mga klase, na may mga larangan at pamamaraan. Ito ay seryosong pag-unlad, magaling! Ngunit ngayon kailangan kong sabihin sa iyo ang isang hindi kasiya-siyang katotohanan. Hindi namin ginawa ang aming mga klase nang tama! Bakit? Sa unang tingin, walang mga error sa klase na ito:
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!");
   }
}
Sa katunayan, mayroon. Isipin na habang nakaupo sa trabaho ay nagsulat ka ng isang klase na tulad nito Cat, na tumutukoy sa mga pusa. At umuwi na siya. Habang wala ka, isa pang programmer ang dumating sa trabaho, gumawa ng sarili niyang klase Main, kung saan sinimulan niyang gamitin ang klase na isinulat mo Cat.
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";
       cat.age = -1000;
       cat.weight = 0;
   }
}
Hindi mahalaga kung bakit niya ginawa ito o kung paano ito nangyari: marahil ang tao ay pagod o hindi sapat na tulog. Ang isa pang bagay ay mahalaga: Catpinapayagan ka ng aming kasalukuyang klase na magtalaga ng mga nakatutuwang halaga sa mga patlang. Bilang resulta, ang programa ay naglalaman ng mga bagay na may hindi tamang estado, tulad ng pusang ito na may edad na -1000 taon. Anong pagkakamali ang nagawa natin? Noong ginawa namin ang klase, inilantad namin ang data nito. Fields name, ageat weightnasa pampublikong domain. Maa-access ang mga ito kahit saan sa programa: lumikha lang ng isang bagay Cat- at iyon lang, ang sinumang programmer ay may access sa data nito nang direkta sa pamamagitan ng " ." operator
Cat cat = new Cat();
cat.name = "";
Dito namin direktang ina-access ang field nameat itinakda ang halaga nito. Kailangan naming protektahan ang aming data mula sa maling panghihimasok sa labas. Ano ang kailangan para dito? Una, ang lahat ng mga variable ng instance (mga patlang) ay dapat na markahan ng isang modifier private. Pribado ang pinakamahigpit na access modifier sa Java. Kung gagamitin mo ito, ang mga field ng klase Catay hindi maa-access sa labas nito.
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!
   }
}
Nakikita ito ng compiler at agad na gumagawa ng isang error. Ngayon ang mga patlang ay tila protektado. Ngunit lumalabas na ang pag-access sa kanila ay "mahigpit" na sarado: ang programa ay hindi maaaring makuha ang bigat ng isang umiiral na pusa, kung kinakailangan. Hindi rin ito isang opsyon: sa form na ito ang aming klase ay halos imposibleng gamitin. Sa isip, kailangan nating payagan ang ilang uri ng limitadong pag-access sa data:
  • Ang ibang mga programmer ay dapat na makalikha ng mga bagayCat
  • Dapat nilang mabasa ang data mula sa mga umiiral nang bagay (halimbawa, kunin ang pangalan o edad ng isang dati nang pusa)
  • Posible rin na magtalaga ng mga halaga ng field. Ngunit sa parehong oras - mga tamang halaga lamang. Ang ating mga bagay ay dapat protektahan mula sa mga maling bagay (walang "edad = -1000 taon" at mga katulad nito).
Ang listahan ng mga kinakailangan ay disente! Ngunit sa katunayan, ang lahat ng ito ay madaling makamit gamit ang mga espesyal na pamamaraan - getters at setters .
Getters at setter - 2
Ang pangalan ay nagmula sa English na “ get ” - “ receive ” (ibig sabihin, “paraan para sa pagkuha ng value ng isang field”) at set - “ set ” (i.e., “paraan para sa pagtatakda ng value ng isang field”). Tingnan natin kung ano ang hitsura nila gamit ang aming klase bilang isang halimbawa 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;
   }
}
Tulad ng nakikita mo, ang lahat ay medyo simple :) Ang kanilang mga pangalan ay kadalasang binubuo ng salitang get/set + ang pangalan ng field kung saan sila responsable. Halimbawa, getWeight()ibinabalik ng isang paraan ang field value weightng object kung saan ito tinawag. Ito ang hitsura nito sa programa:
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);
   }
}
Output ng console:

Name кота: Барсик
Возраст кота: 5
Вес кота: 4
Ngayon mula sa ibang klase ( Main) mayroong access sa mga field Cat, ngunit sa pamamagitan lamang ng mga getter . Pakitandaan na ang mga getter ay may access modifier public, ibig sabihin, naa-access sila kahit saan sa programa. Paano ang tungkol sa pagtatalaga ng mga halaga? Ang mga pamamaraan ng setter ay responsable para dito
public void setName(String name) {
   this.name = name;
}
Ang kanilang trabaho, tulad ng nakikita mo, ay simple din. Tinatawag namin ang isang pamamaraan setName()sa isang bagay Cat, ipasa ito ng isang string bilang isang argumento, at ang string na ito ay itinalaga sa isang patlang nameng aming bagay.
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());
   }
}
Dito ginamit namin ang parehong mga getter at setter. Una, gamit ang isang getter, natanggap namin at na-output sa console ang unang pangalan ng pusa. Pagkatapos, gamit ang isang setter, nameisang bagong halaga ang itinalaga sa field nito - "Vasily". At pagkatapos, gamit ang isang getter, nakuha namin muli ang pangalan upang suriin kung talagang nagbago ito. Output ng console:

Изначальное Name кота — Барсик
Новое Name кота — Васorй
Mukhang, ano ang pagkakaiba? Maaari rin kaming magtalaga ng mga maling halaga sa mga patlang ng bagay, kahit na mayroon kaming mga setter:
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");
   }
}
Output ng console:

Возраст Барсика — -1000 лет
Ang pagkakaiba ay ang isang setter ay isang ganap na paraan . At sa isang paraan, hindi tulad ng isang field, maaari mong ilagay ang lohika ng pag-verify na kailangan mo upang maiwasan ang mga hindi katanggap-tanggap na halaga. Halimbawa, madali mong hindi paganahin ang pagtatalaga ng negatibong numero bilang edad:
public void setAge(int age) {
   if (age >= 0) {
       this.age = age;
   } else {
       System.out.println("Error! Age cannot be negative!");
   }
}
At ngayon ang aming code ay gumagana nang tama!
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");
   }
}
Output ng console:

Ошибка! Возраст не может быть отрицательным числом!
Возраст Барсика — 5 лет
Mayroong paghihigpit sa loob ng setter, at pinoprotektahan nito laban sa mga pagtatangka na magtakda ng maling data. Ang edad ni Barsik ay nanatiling hindi nagbabago. Dapat palaging gawin ang mga getter at setter. Kahit na ang iyong mga field ay walang mga paghihigpit sa mga posibleng halaga, walang magiging pinsala mula sa kanila. Isipin ang isang sitwasyon: ikaw at ang iyong mga kasamahan ay nagsusulat ng isang programa nang magkasama. Gumawa ka ng klase Catna may mga pampublikong field, at ginagamit ng lahat ng programmer ang mga ito ayon sa gusto nila. At pagkatapos ay isang magandang araw ay bumungad sa iyo: "Damn, sa malao't madali ay maaaring may hindi sinasadyang magtalaga ng negatibong numero sa isang variable weight! Kailangan nating gumawa ng mga setter at gawing pribado ang lahat ng field!” Gagawin mo ang mga ito, at ang lahat ng code na isinulat ng iyong mga kasamahan ay agad na masira. Pagkatapos ng lahat, nagsulat na sila ng isang bungkos ng code kung saan Catdirektang na-access nila ang mga patlang.
cat.name = "Hippopotamus";
At ngayon ang mga patlang ay naging pribado at ang compiler ay gumagawa ng isang grupo ng mga error!
cat.name = "Hippopotamus";//error! The name field of the Cat class has private access!
Sa ganoong sitwasyon, mas mainam na itago ang mga field at lumikha ng mga getter-setter mula pa sa simula . Gagamitin ng lahat ng iyong mga kasamahan ang mga ito, at kung huli mong nalaman na kailangan mong limitahan ang mga halaga ng field, magdaragdag ka lang ng tseke sa loob ng setter. At walang makakasira sa nakasulat na code. Siyempre, kung gusto mo ng read-only na access sa isang partikular na field, maaari kang lumikha ng isang getter para dito. "Sa labas", iyon ay, sa labas ng iyong klase, ang mga pamamaraan lamang ang dapat ma-access. Dapat nakatago ang data.
Getters at setter - 4
Ang isang pagkakatulad ay maaaring gawin sa isang mobile phone. Isipin na sa halip na isang regular na mobile phone ang naka-on, binigyan ka ng isang telepono na may bukas na case, kung saan ang lahat ng mga wire, circuit, atbp. lumalabas. Gumagana ang telepono: kung susubukan mong mabuti at kalikot sa mga diagram, maaari ka pang tumawag. Pero baka masira mo lang. Sa halip, ang kumpanya ng pagmamanupaktura ay nagbibigay sa iyo ng isang interface: ang kliyente ay dina-dial lamang ang mga kinakailangang numero, pinindot ang berdeng buton gamit ang handset, at magsisimula ang tawag. At wala siyang pakialam kung ano ang nangyayari sa loob ng mga circuit at wire at kung paano nila ginagawa ang kanilang gawain. Sa halimbawang ito, ang kumpanya ay may limitadong access sa "mga panloob" (data) ng telepono at iniwan lamang ang interface (mga pamamaraan) sa labas. Bilang resulta, makukuha ng kliyente ang gusto niya (tumawag) at tiyak na walang masisira sa loob.
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION