Anonimni tečajevi na Javi

1. Uvod

U ovom uputstvu razmotrit ćemo anonimne razrede u Javi.

Opisat ćemo kako ih možemo prijaviti i stvoriti. Također ćemo ukratko razgovarati o njihovim svojstvima i ograničenjima.

2. Anonimna razredna deklaracija

Anonimni razredi su unutarnji razredi bez imena. Budući da nemaju ime, ne možemo ih koristiti za stvaranje instanci anonimnih klasa. Kao rezultat, na mjestu upotrebe moramo deklarirati i aktivirati anonimne klase u jednom izrazu.

Možemo ili proširiti postojeću klasu ili implementirati sučelje.

2.1. Proširite razred

Kada instanciramo anonimnu klasu iz postojeće, koristimo sljedeću sintaksu:

U zagradi navodimo parametre koji su potrebni konstruktoru klase koju proširujemo:

nova knjiga ("Uzorci dizajna") {@Preuzmi javni opis niza () {return "Poznata knjiga GoF-a."; }}

Naravno, ako konstruktor roditeljske klase ne prihvati nikakve argumente, zagrade bismo trebali ostaviti prazne.

2.2. Implementirati sučelje

Anonimnu klasu možemo instancirati i sa sučelja:

Očito je da Java sučelja nemaju konstruktore, tako da zagrade uvijek ostaju prazne. Ovo je jedini način na koji bismo to trebali učiniti kako bismo implementirali metode sučelja:

novi Runnable () {@Preuzmi javno void vođenje () {...}}

Nakon što instanciramo anonimnu klasu, možemo je dodijeliti varijabli kako bismo je mogli negdje kasnije uputiti.

To možemo učiniti pomoću standardne sintakse za Java izraze:

Izvodljiva radnja = nova Izvodiva () {@Preuzmi javno void vođenje () {...}};

Kao što smo već spomenuli, anonimna deklaracija klase je izraz, stoga mora biti dio izjave. To objašnjava zašto smo na kraj izjave stavili zarez i zarez.

Očito možemo izbjeći dodjeljivanje instance varijabli ako tu instancu izradimo u redu:

Popis akcija = novi ArrayList (); actions.add (new Runnable () {@Preuzmi javno void vođenje () {...}});

Ovu bismo sintaksu trebali koristiti s velikom pažnjom, jer bi lako mogla pretrpjeti čitljivost koda, posebno kada je implementacija trčanje() metoda zauzima puno prostora.

3. Anonimna svojstva klase

Postoje određene posebnosti u korištenju anonimnih klasa u odnosu na uobičajene klase najviše razine. Ovdje ćemo ukratko dodirnuti najpraktičnija pitanja. Za najpreciznije i najnovije informacije uvijek možemo pogledati Specifikaciju jezika Java.

3.1. Konstruktor

Sintaksa anonimnih klasa ne dopušta nam da ih natjeramo da implementiraju više sučelja. Tijekom gradnje, mogao bi postojati točno jedan primjerak anonimne klase. Stoga oni nikada ne mogu biti apstraktni. Budući da nemaju ime, ne možemo ih proširiti. Iz istog razloga anonimne klase ne mogu imati eksplicitno deklarirane konstruktore.

U stvari, odsutnost konstruktora ne predstavlja nam problem iz sljedećih razloga:

  1. izrađujemo anonimne instance klase u istom trenutku kada ih i deklariramo
  2. iz anonimnih instanci klase možemo pristupiti lokalnim varijablama i pridružiti članove klase

3.2. Statični članovi

Anonimne klase ne mogu imati statičke članove, osim onih koji su konstantni.

Na primjer, ovo se neće kompajlirati:

new Runnable () {static final int x = 0; statički int y = 0; // pogreška kompilacije! @Preuzmi javni void run () {...}};

Umjesto toga, dobit ćemo sljedeću pogrešku:

Polje y ne može se proglasiti statičkim u nestatičnom unutarnjem tipu, osim ako je inicijalizirano konstantnim izrazom

3.3. Opseg varijabli

Anonimne klase hvataju lokalne varijable koje se nalaze u opsegu bloka u kojem smo deklarirali klasu:

broj brojeva = 1; Izvodljiva radnja = nova Izvodiva () {@Preuzmi javno void vođenje () {System.out.println ("Izvodljiva sa zarobljenim varijablama:" + count); }}; 

Kao što vidimo, lokalne varijable računati i akcijski definirani su u istom bloku. Iz tog razloga možemo pristupiti računati iz deklaracije klase.

Imajte na umu da da bi mogle koristiti lokalne varijable, one moraju biti učinkovito konačne. Od JDK 8 više nije potrebno deklarirati varijable s ključnom riječi konačni. Ipak, te varijable moraju biti konačni. U suprotnom dobivamo pogrešku pri kompilaciji:

[ERROR] lokalne varijable na koje se upućuje iz unutarnje klase moraju biti konačne ili zapravo konačne

Da bi kompajler odlučio da je varijabla u stvari nepromjenjiva, u kodu treba postojati samo jedno mjesto na kojem joj dodijeljujemo vrijednost. Više informacija o učinkovito konačnim varijablama mogli bismo pronaći u našem članku "Zašto lokalne varijable koje se koriste u lambdama moraju biti konačne ili efektivno konačne?"

Spomenimo samo da kao i svaki unutarnji razred, anonimna klasa može pristupiti svim članovima svoje zatvorene klase.

4. Slučajevi anonimne nastave

Može postojati velika raznolikost aplikacija anonimnih klasa. Istražimo neke moguće slučajeve upotrebe.

4.1. Razredna hijerarhija i inkapsulacija

Trebali bismo koristiti interne klase za opće slučajeve, a anonimne za vrlo specifične kako bismo postigli čišću hijerarhiju klasa u našoj aplikaciji. Kada koristimo unutarnje klase, možemo postići finiju inkapsulaciju podataka klase koja obuhvaća. Ako definiramo funkcionalnost unutarnje klase u klasi najviše razine, tada bi trebala pripadajuća klasa javnost ili paket vidljivost nekih njegovih članova. Prirodno, postoje situacije kada se to ne cijeni ili čak prihvaća.

4.2. Struktura čistijeg projekta

Anonimne satove obično koristimo kada ih moramo izmijeniti u letu primjena metoda nekih klasa. U ovom slučaju možemo izbjeći dodavanje novog *.Java datoteke u projekt kako bi se definirale klase najviše razine. To je osobito istinito ako bi se ta klasa najviše razine koristila samo jednom.

4.3. Slušatelji događaja korisničkog sučelja

U aplikacijama s grafičkim sučeljem najčešći slučaj anonimnih klasa je stvaranje različitih slušatelja događaja. Na primjer, u sljedećem isječku:

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

kreiramo instancu anonimne klase koja implementira sučelje ActionListener. Njegova actionPerformed metoda aktivira se kada korisnik klikne gumb.

Od Jave 8, čini se da su lambda izrazi ipak preferiraniji način.

5. Općenita slika

Anonimne klase koje smo gore razmatrali samo su poseban slučaj ugniježđenih klasa. Općenito, ugniježđena klasa je klasa koja je deklarirana unutar druge klase ili sučelja:

Gledajući dijagram, vidimo da anonimni razredi zajedno s lokalno i one nestatične članove čine tzv unutarnja nastava. Zajedno s statični član klase, oni čine ugniježđene klase.

6. Zaključak

U ovom smo članku razmotrili različite aspekte anonimnih tečajeva Java. Opisali smo i opću hijerarhiju ugniježđenih klasa.

Kao i uvijek, cjeloviti kôd dostupan je u našem GitHub spremištu.