CodeGym/Java Blog/Willekeurig/Getters en setters
John Squirrels
Niveau 41
San Francisco

Getters en setters

Gepubliceerd in de groep Willekeurig
Hallo! In voorgaande colleges heb je al geleerd hoe je met methodes en velden je eigen volwaardige klassen kunt declareren. In de les van vandaag zullen we het hebben over Getters en Setters in Java. Dit is een serieuze vooruitgang, goed gedaan! Maar nu moet ik je een onaangename waarheid vertellen. We hebben onze klassen niet correct opgegeven! Waarom? Op het eerste gezicht heeft de volgende klasse geen fouten:
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!");
   }
}
Maar dat doet het wel. Stel je voor dat je op je werk zit en schrijf deze Cat- les om katten te vertegenwoordigen. En dan ga je naar huis. Terwijl jij weg bent, arriveert een andere programmeur op het werk. Hij maakt zijn eigen Main- klasse, waar hij de door u geschreven Cat- klasse begint te gebruiken .
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";
       cat.age = -1000;
       cat.weight = 0;
   }
}
Het maakt niet uit waarom hij het deed en hoe het gebeurde (misschien is de man moe of heeft hij niet genoeg geslapen). Iets anders is van belang: onze huidige Cat- klasse staat toe dat velden absoluut krankzinnige waarden krijgen. Als resultaat heeft het programma objecten met een ongeldige status (zoals deze kat die -1000 jaar oud is). Dus welke fout hebben we gemaakt bij het declareren van onze klasse? We hebben de gegevens van onze klas openbaar gemaakt. De velden naam, leeftijd en gewicht zijn openbaar. Ze zijn overal in het programma toegankelijk: maak gewoon een Cat- object aan en elke programmeur heeft directe toegang tot de gegevens via de puntoperator ( . ).
Cat cat = new Cat();
cat.name = "";
Hier hebben we rechtstreeks toegang tot het naamveld en stellen we de waarde in. We moeten onze gegevens op de een of andere manier beschermen tegen ongepaste externe inmenging. Wat hebben we daarvoor nodig? Eerst moeten alle instantievariabelen (velden) worden gemarkeerd met de private modifier. Private is de strengste toegangsmodifier in Java. Zodra u dit doet, zijn de velden van de Cat- klasse niet toegankelijk buiten de klasse.
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 Cat class's name field is private!
   }
}
De compiler ziet dit en genereert onmiddellijk een fout. Nu zijn de velden min of meer beschermd. Maar het blijkt dat we de toegang misschien te strak hebben afgesloten: je kunt het gewicht van een bestaande kat niet in het programma krijgen, zelfs als dat nodig is. Ook dit is geen optie. Zoals het nu is, is onze klas in wezen onbruikbaar. Idealiter moeten we een soort van beperkte toegang toestaan:
  • Andere programmeurs zouden Cat- objecten moeten kunnen maken
  • Ze moeten gegevens van bestaande objecten kunnen lezen (bijvoorbeeld de naam of leeftijd van een bestaande kat opvragen)
  • Het moet ook mogelijk zijn om veldwaarden toe te wijzen. Maar hierbij mogen alleen geldige waarden worden toegestaan. Onze objecten moeten worden beschermd tegen ongeldige waarden (bijv. leeftijd = -1000, enz.).
Dat is een behoorlijke lijst met eisen! In werkelijkheid wordt dit allemaal eenvoudig bereikt met speciale methoden die getters en setters worden genoemd.
Getters en setters - 2
Deze namen komen van "get" (dwz "methode om de waarde van een veld te krijgen") en "set" (dwz "methode om de waarde van een veld in te stellen"). Laten we eens kijken hoe ze eruit zien in onze Cat- klasse :
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;
   }
}
Zoals je kunt zien, zien ze er vrij eenvoudig uit :) Hun namen bestaan ​​vaak uit "get"/"set" plus de naam van het relevante veld. De methode getWeight() retourneert bijvoorbeeld de waarde van het gewichtsveld voor het object waarop het wordt aangeroepen. Zo ziet het eruit in een programma:
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);
       String smudgeName = smudge.getName();
       int smudgeAge = smudge.getAge();
       int smudgeWeight = smudge.getWeight();

       System.out.println("Cat's name: " + smudgeName);
       System.out.println("Cat's age: " + smudgeAge);
       System.out.println("Cat's weight: " + smudgeWeight);
   }
}
Console-uitvoer:
Cat's name: Smudge
Cat's age: 5
Cat's weight: 4
Nu heeft een andere klasse ( Main ) toegang tot de Cat- velden, maar alleen via getters. Merk op dat getters de public access modifier hebben, dwz dat ze overal in het programma beschikbaar zijn. Maar hoe zit het met het toekennen van waarden? Dit is waar setter-methoden voor zijn
public void setName(String name) {
   this.name = name;
}
Zoals je kunt zien, zijn ze ook eenvoudig. We roepen de methode setName() op een Cat- object aan, geven een tekenreeks door als argument en de tekenreeks wordt toegewezen aan het naamveld van het object.
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);

       System.out.println("Cat's original name: " + smudge.getName());
       smudge.setName("Mr. Smudge");
       System.out.println("Cat's new name: " + smudge.getName());
   }
}
Hier gebruiken we zowel getters als setters. Eerst gebruiken we een getter om de originele naam van de kat te krijgen en weer te geven. Vervolgens gebruiken we een setter om een ​​nieuwe naam toe te wijzen ("Mr. Smudge"). En dan gebruiken we de getter nogmaals om de naam te krijgen (om te controleren of deze echt is veranderd). Console-uitvoer:
Cat's original name: Smudge
Cat's new name: Mr. Smudge
Dus wat is het verschil? We kunnen nog steeds ongeldige waarden toewijzen aan velden, zelfs als we setters hebben:
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);
       smudge.setAge(-1000);

       System.out.println("Smudge's age: " + smudge.getAge());
   }
}
Console-uitvoer:
Smudge's age: -1000 years
Het verschil is dat een setter een volwaardige methode is. En in tegenstelling tot een veld kunt u met een methode de verificatielogica schrijven die nodig is om onaanvaardbare waarden te voorkomen. U kunt bijvoorbeeld eenvoudig voorkomen dat een negatief getal als leeftijd wordt toegewezen:
public void setAge(int age) {
   if (age >= 0) {
       this.age = age;
   } else {
       System.out.println("Error! Age can't be negative!");
   }
}
En nu werkt onze code correct!
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);
       smudge.setAge(-1000);

       System.out.println("Smudge's age: " + smudge.getAge());
   }
}
Console-uitvoer:
Error! Age can't be negative!
Smudge's age: 5 years
Binnen de setter hebben we een beperking gecreëerd die ons beschermde tegen de poging om ongeldige gegevens in te stellen. Smudge's leeftijd is niet veranderd. Je moet altijd getters en setters maken. Zelfs als er geen beperkingen zijn aan de waarden die uw velden kunnen aannemen, kunnen deze hulpmethoden geen kwaad. Stel je de volgende situatie voor: je schrijft samen met je collega's een programma. U maakt een Cat- klasse met openbare velden. Alle programmeurs gebruiken ze zoals ze willen. En dan realiseer je je op een mooie dag: "Klopt, vroeg of laat kan iemand per ongeluk een negatief getal toekennen aan het gewicht! We moeten setters maken en alle velden privé maken!" Je doet precies dat en kraakt meteen alle code die door je collega's is geschreven. Ze zijn immersKattenvelden direct.
cat.name = "Behemoth";
En nu zijn de velden privé en spuwt de compiler een hoop fouten!
cat.name = "Behemoth";//error! The Cat class's name field is private!
In dit geval zou het beter zijn om de velden te verbergen en vanaf het allereerste begin getter en setters te maken. Al je collega's zouden ze hebben gebruikt. En als u zich te laat realiseerde dat u de veldwaarden op de een of andere manier moest beperken, had u de cheque gewoon in de setter kunnen schrijven. En niemands code zou worden gekraakt. Als u wilt dat de toegang tot een veld alleen "alleen-lezen" is, kunt u er natuurlijk alleen een getter voor maken. Alleen methoden zouden extern beschikbaar moeten zijn (dwz buiten je klas). Gegevens moeten worden verborgen. We zouden een vergelijking kunnen maken met een mobiele telefoon. Stel je voor dat je in plaats van de gebruikelijke gesloten mobiele telefoon een telefoon krijgt met een open behuizing, met allerlei uitstekende draden, schakelingen, enz. Maar de telefoon werkt: als je heel hard je best doet en in de schakelingen prikt, word je misschien zelfs kunnen bellen. Maar jij'
Getters en setters - 3
In plaats daarvan geeft de fabrikant u een interface: de gebruiker voert eenvoudig de juiste cijfers in, drukt op de groene belknop en het gesprek begint. Het kan haar niet schelen wat er binnen gebeurt met de circuits en draden, of hoe ze hun werk doen. In dit voorbeeld beperkt het bedrijf de toegang tot de "binnenkant" (gegevens) van de telefoon en stelt alleen een interface (methoden) bloot. Als gevolg hiervan krijgt de gebruiker wat ze wilde (de mogelijkheid om te bellen) en zal er zeker niets kapot gaan. Om te versterken wat je hebt geleerd, raden we je aan een videoles van onze Java-cursus te bekijken
Opmerkingen
  • Populair
  • Nieuw
  • Oud
Je moet ingelogd zijn om opmerkingen te kunnen maken
Deze pagina heeft nog geen opmerkingen