Névtelen órák Java-ban

1. Bemutatkozás

Ebben az oktatóanyagban a Java névtelen osztályait vesszük figyelembe.

Leírjuk, hogyan deklarálhatjuk és létrehozhatjuk azok példányait. Röviden áttekintjük tulajdonságait és korlátait is.

2. Névtelen osztálynyilatkozat

Az anonim osztályok név nélküli belső osztályok. Mivel nincs nevük, nem használhatjuk őket névtelen osztályok példányainak létrehozására. Ennek eredményeként az anonim osztályokat egyetlen kifejezésben kell deklarálnunk és példányosítanunk a használat helyén.

Vagy kibővíthetünk egy meglévő osztályt, vagy megvalósíthatunk egy interfészt.

2.1. Hosszabbítson egy osztályt

Amikor egy névtelen osztályt létezőből példányosítunk, a következő szintaxist használjuk:

A zárójelben megadjuk azokat a paramétereket, amelyekre a kibővítendő osztály konstruktora szükséges:

új könyv ("Design Patterns") {@Orride public String description () {return "Famous GoF book."; }}

Természetesen, ha a szülő osztály konstruktora nem fogad el argumentumokat, akkor a zárójeleket üresen kell hagynunk.

2.2. Interfész megvalósítása

Egy anonim osztályt is létrehozhatunk egy felületről:

Nyilvánvaló, hogy a Java felületein nincsenek konstruktorok, ezért a zárójelek mindig üresek maradnak. Csak így kell megtenni a felület metódusainak megvalósítását:

új Runnable () {@Orride public void run () {...}}

Miután létrehoztunk egy névtelen osztályt, hozzárendelhetjük azt a példányt egy változóhoz, hogy később valahova hivatkozhassunk rá.

Ezt a Java kifejezések szabványos szintaxisával tehetjük meg:

Futható művelet = új Futható () {@Orride public void run () {...}};

Mint már említettük, az anonim osztály deklaráció kifejezés, ezért annak egy állítás részének kell lennie. Ez megmagyarázza, miért tettünk pontosvesszőt az állítás végére.

Nyilvánvaló, hogy elkerülhetjük a példány hozzárendelését egy változóhoz, ha a példányt inline hozzuk létre:

Lista műveletek = new ArrayList (); actions.add (new Runnable () {@Orride public void run () {...}});

Ezt a szintaxist nagyon körültekintően kell használnunk, mivel ez könnyen károsíthatja a kód olvashatóságát, különösen a fuss() módszer sok helyet foglal el.

3. Névtelen osztály tulajdonságai

A névtelen osztályok használatának bizonyos sajátosságai vannak a szokásos legfelső szintű osztályok tekintetében. Itt röviden kitérünk a legpraktikusabb kérdésekre. A legpontosabb és legfrissebb információkért mindig megnézhetjük a Java nyelvi specifikációt.

3.1. Konstruktőr

Az anonim osztályok szintaxisa nem teszi lehetővé számunkra, hogy több felületet valósítsunk meg. Az építkezés során pontosan egy névtelen osztály létezhet. Ezért soha nem lehetnek elvontak. Mivel nincs nevük, nem tudjuk meghosszabbítani őket. Ugyanezen okból az anonim osztályok nem tudták kifejezetten deklarálni a konstruktorokat.

Valójában a kivitelező hiánya nem jelent számunkra problémát a következő okok miatt:

  1. névtelen osztálypéldányokat hozunk létre ugyanabban a pillanatban, amikor deklaráljuk őket
  2. névtelen osztálypéldányokból hozzáférhetünk a helyi változókhoz, és bezárhatjuk az osztály tagjait

3.2. Statikus tagok

Az anonim osztályoknak nem lehetnek statikus tagjai, kivéve azokat, amelyek állandóak.

Például ez nem fordítja le:

új Futható () {statikus végső int x = 0; statikus int y = 0; // összeállítási hiba! @Orride public void run () {...}};

Ehelyett a következő hibát kapjuk:

Az y mezőt nem lehet statikusnak nyilvánítani nem statikus belső típusban, hacsak konstans kifejezéssel nem inicializáljuk

3.3. A változók köre

Az anonim osztályok olyan lokális változókat rögzítenek, amelyek azon blokk hatókörébe tartoznak, amelyben az osztályt deklaráltuk:

int szám = 1; Futható művelet = új Futható () {@Orride public void run () {System.out.println ("Futtatható változókkal futtatható:" + szám); }}; 

Mint látjuk, a helyi változók számol és akció azonos blokkban vannak meghatározva. Emiatt hozzáférhetünk számol az osztálynyilatkozatból.

Vegye figyelembe, hogy a helyi változók használatához ténylegesen véglegeseknek kell lenniük. A JDK 8 óta már nem szükséges a változók deklarálása a kulcsszóval végső. Ennek ellenére ezeknek a változóknak igen végső. Ellenkező esetben fordítási hibát kapunk:

A belső osztályból hivatkozott [ERROR] helyi változóknak véglegesnek vagy ténylegesen véglegesnek kell lenniük

Annak érdekében, hogy a fordító eldöntse, hogy egy változó valójában megváltoztathatatlan-e a kódban, csak egy helyen szabad értéket rendelni hozzá. A hatékony végső változókról további információt találhatunk „Miért kell a lambdákban használt helyi változóknak véglegesnek vagy ténylegesen véglegesnek lenniük?” Című cikkünkben.

Említsük csak meg, hogy mint minden belső osztály, egy névtelen osztály hozzáférhet a bezáró osztályának minden tagjához.

4. Névtelen osztályhasználati esetek

Lehet, hogy az anonim osztályok nagyon sokféle alkalmazást kínálnak. Fedezzük fel a lehetséges felhasználási eseteket.

4.1. Osztályhierarchia és beágyazás

Belső osztályokat kell használnunk általános felhasználási esetekben, és névteleneket nagyon specifikus osztályokban, hogy tisztább osztályhierarchiát érjünk el alkalmazásunkban. Belső osztályok használatakor a becsatoló osztály adatainak finomabb beágyazását érhetjük el. Ha a belső osztály funkcionalitását egy felső szintű osztályban definiáljuk, akkor a melléklő osztálynak rendelkeznie kell ezzel nyilvános vagy csomag egyes tagjai láthatósága. Természetesen vannak olyan helyzetek, amikor ezt nem nagyon értékelik, sőt nem is fogadják el.

4.2. Tisztább projekt felépítése

Általában névtelen osztályokat használunk, amikor módosítanunk kell menet közben egyes osztályok módszereinek megvalósítása. Ebben az esetben elkerülhetjük az új hozzáadását *.Jáva fájlokat a projektbe a legfelső szintű osztályok meghatározása érdekében. Ez különösen igaz, ha ezt a felső szintű osztályt egyszer használnák.

4.3. UI esemény hallgatók

A grafikus felülettel rendelkező alkalmazásokban az anonim osztályok leggyakoribb felhasználási módja a különféle eseményhallgatók létrehozása. Például a következő részletben:

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

létrehozunk egy anonim osztály példányát, amely megvalósítja az interfészt ActionListener. Az actionPerformed A módszer akkor vált be, amikor a felhasználó rákattint a gombra.

A Java 8 óta mégis a lambda kifejezések tűnnek előnyösebb módnak.

5. Általános kép

A fentieknek tekintett névtelen osztályok csak a beágyazott osztályok sajátos esetei. Általában, egy beágyazott osztály az egy osztály, amelyet egy másik osztályon vagy interfészen belül deklarálnak:

A diagramot nézve azt látjuk, hogy a névtelen osztályok helyi és nem statikus tagok alkotják az ún belső osztályok. Együtt statikus tag osztályok alkotják a beágyazott osztályokat.

6. Következtetés

Ebben a cikkben a Java anonim osztályok különböző aspektusait vettük figyelembe. Leírtuk a beágyazott osztályok általános hierarchiáját is.

Mint mindig, a teljes kód elérhető a GitHub adattárunkban.