Helló! Az előző előadásokon már megtanultad, hogyan deklaráld saját, teljes értékű osztályaidat metódusokkal és mezőkkel. A mai leckében a Java gettereiről és szettereiről fogunk beszélni. Ez komoly előrelépés, jól sikerült! De most el kell mondanom egy kellemetlen igazságot. Nem deklaráltuk megfelelően az óráinkat! Miért? Első ránézésre a következő osztályban nincsenek hibák:
Ezek a nevek a "get" (azaz "egy mező értékének meghatározására szolgáló módszer") és "set" (azaz "egy mező értékének beállítására szolgáló módszer") szavakból származnak. Nézzük meg, hogyan néznek ki a Cat osztályunkban :
Ehelyett a gyártó egy interfészt ad: a felhasználó egyszerűen beírja a megfelelő számjegyeket, megnyomja a zöld hívás gombot, és a hívás megkezdődik. Nem érdekli, mi történik belül az áramkörökkel és vezetékekkel, vagy hogy hogyan végzik el a munkájukat. Ebben a példában a vállalat korlátozza a hozzáférést a telefon "belseihez" (adatok), és csak egy interfészt (módszereket) tesz közzé. Ennek eredményeként a felhasználó azt kapja, amit akart (a hívás lehetőségét), és biztosan nem tör el semmit. A tanultak megerősítése érdekében javasoljuk, hogy nézzen meg egy videóleckét a Java-tanfolyamról
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!");
}
}
De igen. Képzeld el, hogy a munkahelyeden ülsz, és ezt a macskaosztályt a macskák képviseletére írod. És akkor mész haza. Amíg te távol vagy, egy másik programozó érkezik a munkahelyére. Létrehozza saját főosztályát , ahol elkezdi használni az általad írt Cat osztályt.
public class Main {
public static void main(String[] args) {
Cat cat = new Cat();
cat.name = "";
cat.age = -1000;
cat.weight = 0;
}
}
Nem mindegy, hogy miért tette és hogyan történt (lehet, hogy a srác fáradt vagy nem aludt eleget). Valami más is számít: a jelenlegi Cat osztályunk lehetővé teszi a mezőkhöz teljesen őrült értékeket rendelni. Ennek eredményeként a programban vannak érvénytelen állapotú objektumok (például ez a macska, amely -1000 éves). Tehát milyen hibát követtünk el az osztályunk bejelentésekor? Kitettük osztályunk adatait. A név, kor és súly mezők nyilvánosak. Bárhol elérhetők a programban: egyszerűen hozzon létre egy Cat objektumot, és bármely programozó közvetlenül hozzáférhet az adataihoz a pont ( . ) operátoron keresztül.
Cat cat = new Cat();
cat.name = "";
Itt közvetlenül elérjük a név mezőt, és beállítjuk az értékét. Valahogy meg kell védenünk adatainkat a nem megfelelő külső beavatkozásoktól. Mire van szükségünk ehhez? Először minden példányváltozót (mezőt) meg kell jelölni a privát módosítóval. A privát a Java legszigorúbb hozzáférés-módosítója. Ha ezt megtette, a Cat osztály mezői nem lesznek elérhetők az osztályon kívül.
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!
}
}
A fordító ezt látja, és azonnal hibát generál. Most a mezők védettek. De kiderült, hogy talán túl szorosan zártuk le a hozzáférést: egy meglévő macska súlyát nem lehet a programban megadni, még akkor sem, ha muszáj. Ez szintén nem opció. Így az osztályunk gyakorlatilag használhatatlan. Ideális esetben engedélyeznünk kell valamilyen korlátozott hozzáférést:
- Más programozóknak képesnek kell lenniük Cat objektumok létrehozására
- Képesnek kell lenniük meglévő objektumok adatainak olvasására (például megtudni egy meglévő macska nevét vagy életkorát).
- Lehetővé kell tenni a mezőértékek hozzárendelését is. Ennek során azonban csak érvényes értékeket szabad megengedni. Tárgyainkat védeni kell az érvénytelen értékektől (pl. kor = -1000 stb.).

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;
}
}
Amint látja, elég egyszerűnek tűnnek :) A nevük gyakran a "get"/"set" és a megfelelő mező nevéből áll. Például a getWeight() metódus visszaadja a meghívott objektum súlymezőjének értékét. Így néz ki egy programban:
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);
}
}
Konzol kimenet:
Cat's name: Smudge
Cat's age: 5
Cat's weight: 4
Most egy másik osztály ( Main ) érheti el a Cat mezőket, de csak gettereken keresztül. Vegye figyelembe, hogy a getterek rendelkeznek a nyilvános hozzáférés módosítóval, azaz a program bármely pontjáról elérhetők. De mi a helyzet az értékek hozzárendelésével? Erre valók a setter módszerek
public void setName(String name) {
this.name = name;
}
Mint látható, ezek is egyszerűek. Meghívjuk a setName() metódust egy Cat objektumon, egy karakterláncot adunk át argumentumként, és a karakterlánc hozzá van rendelve az objektum névmezőjéhez.
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());
}
}
Itt gettereket és settereket is használunk. Először egy gettert használunk, hogy megkapjuk és megjelenítsük a macska eredeti nevét. Ezután egy setter segítségével új nevet adunk ("Mr. Smudge"). Ezután még egyszer használjuk a gettert, hogy megkapjuk a nevet (ellenőrizzük, hogy valóban megváltozott-e). Konzol kimenet:
Cat's original name: Smudge
Cat's new name: Mr. Smudge
Szóval mi a különbség? Még akkor is hozzárendelhetünk érvénytelen értékeket a mezőkhöz, ha vannak beállítóink:
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());
}
}
Konzol kimenet:
Smudge's age: -1000 years
A különbség az, hogy a szetter egy teljes értékű módszer. A mezőkkel ellentétben a metódusok lehetővé teszik az elfogadhatatlan értékek megakadályozásához szükséges ellenőrzési logika megírását. Könnyedén megakadályozhatja például, hogy egy negatív szám életkorként legyen hozzárendelve:
public void setAge(int age) {
if (age >= 0) {
this.age = age;
} else {
System.out.println("Error! Age can't be negative!");
}
}
És most a kódunk megfelelően működik!
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());
}
}
Konzol kimenet:
Error! Age can't be negative!
Smudge's age: 5 years
A beállítón belül létrehoztunk egy korlátozást, amely megvédett minket az érvénytelen adatok beállításának kísérletétől. Smudge életkora nem változott. Mindig hozzon létre gettereket és settereket. Még ha nincsenek korlátozások arra vonatkozóan, hogy a mezők milyen értékeket vehetnek fel, ezek a segédmódszerek nem ártanak. Képzelje el a következő helyzetet: Ön és kollégái közösen írnak programot. Létrehoz egy Cat osztályt nyilvános mezőkkel. Minden programozó úgy használja őket, ahogy akarja. És aztán egy szép napon rájössz: "A szar, előbb-utóbb valaki véletlenül negatív számot rendel a súlyhoz! Szállítókat kell létrehoznunk, és az összes mezőt priváttá kell tenni!" Ön éppen ezt teszi, és azonnal feltöri a kollégái által írt összes kódot. Végül is ők'Macska mezők közvetlenül.
cat.name = "Behemoth";
És most a mezők privátak, és a fordító egy csomó hibát kidob!
cat.name = "Behemoth";//error! The Cat class's name field is private!
Ebben az esetben jobb lenne elrejteni a mezőket, és már az elején létrehozni gettereket és szettereket. Minden kollégája használta volna őket. És ha későn vette észre, hogy valahogy korlátoznia kell a mezőértékeket, akkor a csekket beírhatta volna a beállítóba. És senkinek a kódja nem törne össze. Természetesen, ha azt szeretné, hogy egy mezőhöz csak "csak olvasható" legyen a hozzáférés, akkor csak egy gettert hozhat létre hozzá. Csak a metódusok legyenek elérhetők kívülről (azaz az osztályon kívül). Az adatokat el kell rejteni. Összehasonlíthatnánk egy mobiltelefonnal. Képzeld el, hogy a szokásos zárt mobiltelefon helyett egy nyitott tokkal ellátott telefont kaptál, mindenféle kilógó vezetékekkel, áramkörökkel stb. De a telefon működik: ha nagyon próbálkozol és piszkálod az áramköröket, még az is lehet, hogy tud hívást kezdeményezni. de te

GO TO FULL VERSION