IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

10. diel - Gettery a settery v Jave

V predchádzajúcom cvičení, Riešené úlohy k 9. lekcii OOP v Jave, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.

Dnes sa v tutoriáli pozrieme na tzv. gettery a settery.

Gettery a settery

Veľmi často sa nám stáva, že chceme mať kontrolu nad zmenami nejakého atribútu objektu zvonku. Budeme chcieť atribút nastaviť ako read-only (len na čítanie) alebo reagovať na jeho zmeny. Založme si nový projekt s názvom napr. GetSet a vytvorme nasledujúcu triedu Student, ktorá bude reprezentovať študenta v nejakom informačnom systéme:

Trieda je veľmi jednoduchá, študent sa nejako volá, je nejakého pohlavia a má určitý vek. Podľa tohto veku sa nastavuje atribút plnolety pre pohodlnejšie vyhodnocovanie plnoletosti na rôznych miestach systému. Na uloženie pohlavia používame hodnotu typu boolean, či je študent muž. Konštruktor podľa veku určí, či je študent plnoletý. Metóda toString() je navrhnutá pre potreby tutoriálu tak, aby nám vypísala všetky informácie. V reáli by vrátila pravdepodobne len meno študenta. Pomocou konštruktora si nejakého študenta vytvorme:

Výstup:

Všetko vyzerá pekne, ale atribúty sú prístupné ako na čítanie, tak na zápis. Objekt teda môžeme rozbiť napríklad takto (hovoríme o nekonzistentnom vnútornom stave):

Výstup:

Určite musíme ošetriť, aby sa plnoletosť obnovila pri zmene veku. Keď sa zamyslíme nad ostatnými atribútmi, nie je najmenší dôvod, aby sme taktiež umožňovali modifikovať pohlavie. Bolo by však zároveň vhodné ich vystaviť na čítanie, nemôžeme ich teda iba nastaviť ako private. V skorších dieloch seriálu sme na tento účel používali metódy, ktoré slúžili na čítanie privátnych atribútov. Ich názov sme volili ako vratVek() a pre nastavenie atribútu napríklad nastavVek(). V Jave sa všetky atribúty, s ktorými sa má pracovať zvonku, označujú ako privátne a pre prístup k nim sa definujú práve podobné metódy. Na ich pomenovanie sa ustálilo getNazevAtributu() na čítanie a setNazevAtributu() na zápis. Ak je atribút typu boolean, volá sa getter isNazevAtributu(). Trieda by novo vyzerala napr. takto:

Metódy, čo hodnoty iba vracajú, sú veľmi jednoduché. Nastavenie veku má už nejakú vnútornú logiku, pri jeho zmene musíme totiž prehodnotiť atribút plnolety. Zaistili sme, že sa do premenných nedá zapisovať inak, než my chceme. Máme teda pod kontrolou všetky zmeny atribútov a dokážeme na ne reagovať. Nemôže sa stať, že by nám niekto vnútorný stav nekontrolovane menil a rozbil. Všimnite si aj zmeny v konštruktore, kde sa nastavuje vek metódou setVek().

Metódam na vrátenie hodnoty sa hovorí gettery a metódam pre zápis settery. Pre editáciu ostatných atribútov by sme urobili jednu metódu editujStudenta(), ktorá by bola podobná konštruktoru.

Otázkou je, aká je teraz výhoda toho, že je atribút jmeno privátne, keď do neho ide zapisovať a možno z neho aj čítať. Veď máme v kóde zbytočne 2 metódy, ktoré tam zaberajú miesto a ešte je to pomalé?

Naozaj sme to napísali správne, alebo aspoň tak, ako sa to bežne robí. Java pred kompiláciou vykonáva početné optimalizácie a pokiaľ sú metódy tak jednoduché, že iba vracajú hodnotu alebo ju nastavujú, metóda sa skompiluje ako priamy prístup do pamäte. Sú teda rovnako rýchle, ako keby sme pracovali s verejným atribútom (za predpokladu, že setter alebo getter nemá nejakú ďalšiu logiku).

IDE dokáže gettery a settery automaticky generovať, nemusíme ich teda otrocky opisovať. Stačí na privátnu premennú kliknúť pravým tlačidlom a zvoliť položku Refactor -> Encapsulate fields:

  • Automatické generovanie getterov a setterov v IntelliJ - Objektovo orientované programovanie v Jave - Objektovo orientované programovanie v Jave

    V ďalšom dialógu si zaškrtneme, ku ktorým atribútom chceme vygenerovať gettery a settery. My nebudeme chcieť sprístupniť pre zápis atribúty plnolety a muz. Atribút plnolety pôjde zmeniť len zmenením veku študenta. Pohlavie nedáva zmysel meniť vôbec (pokiaľ by to bolo naozaj niekedy potrebné, bola by na to nejaká špeciálna metóda, aby sa vylúčila zmena chybou v kóde). Dialóg potvrdíme:

    Automatické generovanie getterov a setterov v IntelliJ - Objektovo orientované programovanie v Jave - Objektovo orientované programovanie v Jave

    Settery pre atribúty plnolety a muz z triedy teda odstránime.

  • Automatické generovanie getterov a setterov v IDE NetBeans - Objektovo orientované programovanie v Jave - Objektovo orientované programovanie v Jave

    V ďalšom dialógu si zaškrtneme, ku ktorým atribútom chceme vygenerovať gettery a ku ktorým settery. My nebudeme chcieť sprístupniť pre zápis atribúty plnolety a muz. Atribút plnolety pôjde zmeniť len tak, že zmeníme vek študenta. Pohlavie nedáva zmysel meniť vôbec (pokiaľ by to bolo naozaj niekedy potrebné, bola by na to nejaká špeciálna metóda, aby sa vylúčila zmena chybou v kóde). Dialóg potvrdíme:

    Automatické generovanie getterov a setterov v NetBeans IDE - Objektovo orientované programovanie v Jave - Objektovo orientované programovanie v Jave
Optimalizácia pred kompiláciou odstránila rýchlostný problém, ktorý by inak zbytočné volanie metód spôsobovalo. Aj zbytočné písanie metód sme vykompenzovali ich automatickým generovaním. Otázkou zostáva, v čom je písanie metód oproti atribútom výhodnejšie.

Hlavným dôvodom je určitá štandardizácia. Nemusíme premýšľať nad tým, či je daná vlastnosť objektu riešená cez getter alebo atribút, na inštanciu jednoducho vždy voláme metódu začínajúcu slovom get (prípadne is) pokiaľ chceme vlastnosť inštancie čítať, prípadne metódu začínajúcu set, ak ju chceme zmeniť.

Ďalšou výhodou je, že keď sa v budúcnosti rozhodneme, že nejaký atribút chceme urobiť read-only (len na čítanie), jednoducho zmažeme setter. Nemusíme vytvárať getter a meniť viditeľnosť atribútu, čo by zmenilo rozhranie triedy a rozbilo existujúci kód, ktorý by ju používal.

Gettery a settery teda budeme odteraz používať pri všetkých atribútoch, ktoré majú byť zvonku prístupné. V našich triedach sa takmer nebudú vyskytovať atribúty s viditeľnosťou public.

Skúsme si teraz ešte spustiť kód, ktorý predtým rozbil interný stav objektu:

Výstup je už v poriadku:

V nasledujúcom kvíze, Kvíz - Dedičnosť, statika, gettery a settery v Jave OOP, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 635x (9.02 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java

 

Predchádzajúci článok
Riešené úlohy k 9. lekcii OOP v Jave
Všetky články v sekcii
Objektovo orientované programovanie v Jave
Preskočiť článok
(neodporúčame)
Kvíz - Dedičnosť, statika, gettery a settery v Jave OOP
Článok pre vás napísal David Hartinger
Avatar
Užívateľské hodnotenie:
1 hlasov
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David sa informačné technológie naučil na Unicorn University - prestížnej súkromnej vysokej škole IT a ekonómie.
Aktivity