Anonymné triedy v Jave

1. Úvod

V tejto príručke zvážime anonymné triedy v prostredí Java.

Popíšeme, ako môžeme deklarovať a vytvárať ich inštancie. Stručne tiež diskutujeme o ich vlastnostiach a obmedzeniach.

2. Vyhlásenie anonymnej triedy

Anonymné triedy sú vnútorné triedy bez názvu. Pretože nemajú meno, nemôžeme ich použiť na vytvorenie inštancií anonymných tried. Vo výsledku musíme v mieste použitia vyhlásiť a vytvoriť inštanciu anonymných tried v jednom výraze.

Môžeme buď rozšíriť existujúcu triedu, alebo implementovať rozhranie.

2.1. Rozšíriť triedu

Keď vytvoríme inštanciu anonymnej triedy z existujúcej, použijeme nasledujúcu syntax:

V zátvorkách zadáme parametre, ktoré vyžaduje konštruktor triedy, ktorú rozširujeme:

nová kniha („Dizajnové vzory“) {@Override public String description () {návrat „Famous GoF book.“; }}

Prirodzene, ak konštruktor nadradenej triedy neprijíma žiadne argumenty, mali by sme zátvorky nechať prázdne.

2.2. Implementovať rozhranie

Anonymnú triedu môžeme vytvoriť z rozhrania tiež:

Je zrejmé, že rozhrania Java nemajú žiadne konštruktory, takže zátvorky zostávajú vždy prázdne. To je jediný spôsob, ako by sme to mali urobiť, aby sme implementovali metódy rozhrania:

new Runnable () {@Override public void run () {...}}

Po vytvorení inštancie anonymnej triedy môžeme danú inštanciu priradiť k premennej, aby sme ju mohli neskôr niekde odkázať.

Môžeme to urobiť pomocou štandardnej syntaxe pre výrazy Java:

Spustiteľná akcia = nová Spustiteľná () {@Override public void run () {...}};

Ako sme už uviedli, anonymné vyhlásenie triedy je výraz, a preto musí byť súčasťou vyhlásenia. To vysvetľuje, prečo sme na koniec vyhlásenia umiestnili bodkočiarku.

Je zrejmé, že sa môžeme vyhnúť priradeniu inštancie k premennej, ak vytvoríme túto inštanciu vloženú:

Zoznam akcií = nový ArrayList (); actions.add (new Runnable () {@Override public void run () {...}});

Túto syntax by sme mali používať veľmi opatrne, pretože by mohla ľahko utrpieť čitateľnosť kódu, najmä pri implementácii run () metóda zaberá veľa miesta.

3. Vlastnosti anonymnej triedy

Používanie anonymných tried má v porovnaní s obvyklými triedami najvyššej úrovne určité zvláštnosti. Tu sa krátko dotkneme najpraktickejších otázok. Najpresnejšie a najaktuálnejšie informácie nájdete v špecifikácii jazyka Java.

3.1. Konštruktér

Syntax anonymných tried nám neumožňuje implementovať viac rozhraní. Počas výstavby môže existovať presne jedna inštancia anonymnej triedy. Preto nikdy nemôžu byť abstraktné. Keďže nemajú meno, nemôžeme ich predĺžiť. Z rovnakého dôvodu nemôžu anonymné triedy výslovne deklarovať konštruktory.

Absencia konštruktora pre nás v skutočnosti nepredstavuje žiadny problém z nasledujúcich dôvodov:

  1. vytvárame anonymné inštancie triedy v rovnakom okamihu, ako ich deklarujeme
  2. z anonymných inštancií triedy môžeme získať prístup k lokálnym premenným a členom triedy

3.2. Statickí členovia

Anonymné triedy nemôžu mať žiadne statické členy okrem tých, ktoré sú konštantné.

Napríklad sa to nebude kompilovať:

new Runnable () {static final int x = 0; statický int y = 0; // chyba kompilácie! @Override public void run () {...}};

Namiesto toho sa zobrazí nasledujúca chyba:

Pole y nemožno v statickom vnútornom type vyhlásiť za statické, pokiaľ nie je inicializované konštantným výrazom

3.3. Rozsah premenných

Anonymné triedy zachytávajú lokálne premenné, ktoré sú v rozsahu bloku, v ktorom sme triedu vyhlásili:

počet int = 1; Spustiteľná akcia = nový Spustiteľný súbor () {@Override public void run () {System.out.println ("Spustiteľný so zachytenými premennými:" + počet); }}; 

Ako vidíme, lokálne premenné počítať a akcia sú definované v rovnakom bloku. Z tohto dôvodu máme prístup počítať z vyhlásenia triedy.

Upozorňujeme, že aby bolo možné používať miestne premenné, musia byť skutočne konečné. Od verzie JDK 8 sa už nevyžaduje, aby sme deklarovali premenné pomocou kľúčového slova konečné. Tieto premenné však musia byť konečné. V opačnom prípade sa zobrazí chyba kompilácie:

[CHYBA] lokálne premenné odkazované z vnútornej triedy musia byť konečné alebo skutočne konečné

Aby kompilátor rozhodol, že premenná je v skutočnosti nemenná, v kóde by malo byť iba jedno miesto, kde jej priradíme hodnotu. Viac informácií o efektívne konečných premenných môžeme nájsť v našom článku „Prečo musia byť lokálne premenné použité v lambdách konečné alebo efektívne konečné?“

Spomeňme len to, že ako každá vnútorná trieda, anonymná trieda má prístup ku všetkým členom svojej obklopujúcej triedy.

4. Anonymné prípady použitia triedy

Môže existovať veľká škála aplikácií anonymných tried. Poďme preskúmať niektoré možné prípady použitia.

4.1. Hierarchia tried a zapuzdrenie

Mali by sme používať vnútorné triedy vo všeobecnosti a anonymné vo veľmi špecifických prípadoch, aby sme v našej aplikácii dosiahli čistejšiu hierarchiu tried. Pri použití vnútorných tried môžeme dosiahnuť jemnejšie zapuzdrenie údajov uzatvárajúcej triedy. Ak definujeme funkčnosť vnútornej triedy v triede najvyššej úrovne, potom by mala mať priložená trieda verejné alebo balíček viditeľnosť niektorých jej členov. Prirodzene existujú situácie, keď to nie je veľmi cenené alebo dokonca akceptované.

4.2. Čistšia štruktúra projektu

Keď to musíme modifikovať, zvyčajne používame anonymné triedy za chodu implementácia metód niektorých tried. V takom prípade sa môžeme vyhnúť pridávaniu nových * .java súbory do projektu s cieľom definovať triedy najvyššej úrovne. Platí to najmä vtedy, ak by sa táto trieda najvyššej úrovne použila iba raz.

4.3. Poslucháči udalostí používateľského rozhrania

V aplikáciách s grafickým rozhraním je najbežnejším prípadom použitia anonymných tried vytváranie rôznych poslucháčov udalostí. Napríklad v nasledujúcom úryvku:

button.addActionListener (nový ActionListener () {public void actionPerformed (ActionEvent e) {...}}

vytvoríme inštanciu anonymnej triedy, ktorá implementuje rozhranie ActionListener. Jeho actionPerformed metóda sa spustí, keď používateľ klikne na tlačidlo.

Od verzie Java 8 sa však výrazy lambda javia ako preferovanejší spôsob.

5. Všeobecný obraz

Anonymné triedy, ktoré sme zvážili vyššie, sú iba konkrétnym prípadom vnorených tried. Spravidla vnorená trieda je trieda, ktorá je deklarovaná v inej triede alebo rozhraní:

Pri pohľade na diagram vidíme, že anonymné triedy spolu s miestne a nestatické členské tvoria tzv vnútorné triedy. Spolu s statický člen triedy, tvoria vnorené triedy.

6. Záver

V tomto článku sme sa zaoberali rôznymi aspektmi anonymných tried Java. Popísali sme tiež všeobecnú hierarchiu vnorených tried.

Celý kód je ako vždy k dispozícii v našom úložisku GitHub.


$config[zx-auto] not found$config[zx-overlay] not found