OBJEKTINIS PROGRAMAVIMAS
Java getteriai ir setteriai
Getteriai ir setteriai yra metodai, kurie kontroliuoja privačių objekto laukų skaitymą bei keitimą. Tai vienas pagrindinių inkapsuliacijos taikymo būdų Java programose.
Kodėl laukus verta slėpti?
Inkapsuliacija saugo objekto vidinę būseną nuo nekontroliuojamo išorinio keitimo. Dažniausiai:
- klasės atributai deklaruojami su
private; - reikšmė skaitoma per viešą getterį;
- reikšmė keičiama per viešą setterį, jei keitimas leidžiamas;
- setteris gali patikrinti reikšmę prieš ją išsaugodamas.
Getterio ir setterio sukūrimas
public class Knyga {
private String pavadinimas;
public String getPavadinimas() {
return pavadinimas;
}
public void setPavadinimas(String naujasPavadinimas) {
this.pavadinimas = naujasPavadinimas;
}
}Čia tik aprašyta klasė ir jos metodai. Objektas nesukurtas, metodai neiškviesti, todėl niekas nespausdinama.
- Atributas
pavadinimasyraprivate, todėl išorinis kodas jo tiesiogiai nepasiekia. getPavadinimas()yra getteris – jis grąžina dabartinę atributo reikšmę.setPavadinimas(...)yra setteris – jis priima naują tekstą.this.pavadinimasreiškia objekto atributą, onaujasPavadinimas– setterio parametrą.- Klasė pati nusprendžia, kokiais viešais metodais leidžiama skaityti arba keisti jos duomenis.
| Metodas | Paskirtis | Rezultatas |
|---|---|---|
getPavadinimas() | Perskaityti lauką | Grąžina String |
setPavadinimas(...) | Pakeisti lauką | Priima parametrą ir paprastai grąžina void |
this.pavadinimas nurodo objekto lauką, o naujasPavadinimas – setterio parametrą.
Tiesioginė prieiga negalima
Kodas už klasės ribų negali tiesiogiai pasiekti private lauko:
Knyga knyga = new Knyga();
knyga.pavadinimas = "Mažasis princas";
System.out.println(knyga.pavadinimas);error: pavadinimas has private access in Knyga
- Kodas bando tiesiogiai įrašyti reikšmę į
knyga.pavadinimas. - Tačiau atributas
pavadinimaspažymėtasprivate. - Todėl jo negalima nei keisti, nei skaityti už
Knygaklasės ribų. - Kompiliatorius sustabdo programą, tad įprastos konsolės išvesties nėra.
Vietoje to naudojami klasės pateikti vieši metodai:
public class Main {
public static void main(String[] args) {
Knyga knyga = new Knyga();
knyga.setPavadinimas("Mažasis princas");
System.out.println(knyga.getPavadinimas());
}
}Mažasis princas
- Setteris
setPavadinimas()gauna tekstą Mažasis princas. - Kadangi setteris yra pačios klasės metodas, jis gali pakeisti privatų atributą.
- Getteris
getPavadinimas()perskaito išsaugotą reikšmę ir ją grąžina. println()parodo getterio grąžintą pavadinimą.
Duomenų tikrinimas setteryje
Setteris leidžia apsaugoti objekto būseną nuo netinkamų reikšmių. Knygos puslapių skaičius turi būti didesnis už nulį:
public class Knyga {
private int puslapiuSkaicius;
public int getPuslapiuSkaicius() {
return puslapiuSkaicius;
}
public void setPuslapiuSkaicius(int naujasSkaicius) {
if (naujasSkaicius <= 0) {
System.out.println("Puslapių skaičius turi būti teigiamas");
return;
}
this.puslapiuSkaicius = naujasSkaicius;
}
public static void main(String[] args) {
Knyga knyga = new Knyga();
knyga.setPuslapiuSkaicius(96);
System.out.println(knyga.getPuslapiuSkaicius());
knyga.setPuslapiuSkaicius(-5);
System.out.println(knyga.getPuslapiuSkaicius());
}
}96
Puslapių skaičius turi būti teigiamas
96
- Pirmasis setterio iškvietimas perduoda tinkamą reikšmę
96. - Sąlyga
96 <= 0yra klaidinga, todėl atributas sėkmingai pakeičiamas. - Antras iškvietimas perduoda netinkamą reikšmę
-5. - Setteris parodo klaidos pranešimą ir su
returnbaigia darbą dar nepakeitęs atributo. - Todėl paskutinis getterio iškvietimas vis dar grąžina ankstesnę tinkamą reikšmę
96.
Bet kuris išorinis kodas galėtų įrašyti, pavyzdžiui, -5 puslapius ir palikti objektą netinkamos būsenos.
Tik skaitymui skirtas laukas
Ne kiekvienam laukui reikia setterio. Jei pateikiamas tik getteris, išorinis kodas reikšmę gali skaityti, bet negali pakeisti:
public class Knyga {
private final String isbn;
public Knyga(String isbn) {
this.isbn = isbn;
}
public String getIsbn() {
return isbn;
}
public static void main(String[] args) {
Knyga knyga = new Knyga("978-609-01-0000-0");
System.out.println(knyga.getIsbn());
}
}978-609-01-0000-0
- ISBN atributas yra ir
private, irfinal. - Jo reikšmė suteikiama konstruktoriuje kuriant objektą.
- Getteris
getIsbn()leidžia išoriniam kodui reikšmę perskaityti. - Setterio nėra, todėl klasė nesiūlo būdo ISBN pakeisti.
finalpapildomai užtikrina, kad po priskyrimo atributui nebus suteikta kita reikšmė.
boolean getterio pavadinimas
Loginėms savybėms getteris pagal įprastą Java vardų susitarimą dažnai pradedamas is:
public class Knyga {
private boolean perskaityta;
public boolean isPerskaityta() {
return perskaityta;
}
public void setPerskaityta(boolean perskaityta) {
this.perskaityta = perskaityta;
}
public static void main(String[] args) {
Knyga knyga = new Knyga();
knyga.setPerskaityta(true);
System.out.println(knyga.isPerskaityta());
}
}true
- Privatus atributas
perskaitytapradžioje turi numatytąją reikšmęfalse. - Setteris
setPerskaityta(true)pakeičia jį įtrue. - Loginio atributo getteris pavadintas
isPerskaityta(). - Getteris grąžina dabartinę reikšmę, o
println()ją parodo konsolėje.
Pavadinimų susitarimai
- Laukui
pavadinimasnaudojamigetPavadinimas()irsetPavadinimas(...). - Pirmoji lauko pavadinimo raidė metodo dalyje rašoma didžioji.
booleangetteris dažnai vadinamasisPerskaityta().- Setterio parametro tipas turi atitikti lauko tipą.
Ne kiekvienam laukui reikia get ir set
Automatiškai kuriant getterį ir setterį kiekvienam laukui galima susilpninti inkapsuliaciją. Viešink tik tuos veiksmus, kurių iš tikrųjų reikia. Kartais aiškesnis metodas yra perskaitytiPuslapius(10), o ne tiesioginis setPerskaitytaPuslapiu(10), nes jis geriau nusako objekto elgseną.

