Gyakorlati alapok III.
A "névtelen" osztály
A szakirodalom névtelen osztály (anonymous class) névvel illet egy különlegesen létrehozott osztályt, amelynek megértése valójában számomra sem volt egyszerű feladat. A probléma feldolgozásakor jöttem rá: voltaképpen maga az elnevezés félrevezető és értetlenségem mindvégig abból táplálkozott, hogy eme különleges osztályra a névtelenség, az anonimitás fogalmát próbáltam ráerőltetni.
Érvelésünket kezdjük a lehető leglogikusabbal a zseniális Angster Erzsébet egyik könyvéből (Objektumorientált tervezés és programozás, JAVA, 2. kötet - 71. oldal). Egyedül nála láttam olyan Java-kódot, amelyben felismerhető 1 névtelennek mondott osztály működése. Az alábbi szöveg lényegi összefoglalója az ott leírtaknak.
Névtelen osztályt akkor célszerű használnunk:
-
ha az osztályból csakis 1 példányt akarunk létrehozni,
-
ha az osztály deklarációja egyszerű.
Névtelen osztályt kétféleképpen hozhatunk létre:
-
adott osztály kiterjesztésével,
-
interfész létrehozásával (a jelen fejezetben ezzel nem foglalkozunk).
A névtelen osztály 1 már meglévő osztály kiterjesztése. A létrejövő osztály az ősosztály névtelen leszármazottja (Öröklődés (inheritance) című fejezetcsomag). A paraméterlistát teljes egészében az ősosztály konstruktora kezeli le. Az új osztálynak nincs konstruktora, hiszen neve sincs. Az öröklődéses-származtatásos kódmechanizmus ellenére nem használjuk az extends kulcsszót.
import java.util.*;
class Main{
private String nev;
public Main(String nev){
this.nev = nev;
}
public String munkabiras(){
return "Normalis";
}
public String toString(){
return nev + " ("+ munkabiras() + ")";
}
public static void main(String[] args){
Vector munkavallalo = new Vector();
munkavallalo.add(new Main("Adam"));
munkavallalo.add(new Main("Zoli"){
public String munkabiras(){
return "Tulterhelheto";
}
});
munkavallalo.add(new Main("Bela"){
public String munkabiras(){
return "Nem
terhelheto";
}
});
System.out.println(munkavallalo);
}
}
Végeredmény:
[Adam (Normalis), Zoli (Tulterhelheto), Bela (Nem terhelheto)]
A kódban jól észrevehető a névtelen osztály vegytiszta működése a Main osztály "röptében történő" példányosításakor, például:
new Main("Adam").
Látjuk, hogy ez a fajta példányosítás különbözik az eddig megszokottól, hiszen "klasszikus" szabályok szerint így példányosítunk:
Main main = new Main();
Mi a különbség a 2 fajta példányosítás között?
Amit mi Java-programozóként saját programozói felületünkön keresztül láthatunk, hogy "névtelen" példányosításkor az osztályból valóban csak 1 példány jön létre, bár rögtön illesszük hozzá, hogy ezt a mechanizmust a kódon belül többször is megtehetjük. Azonban nincs egyértelműen megszólítható objektumreferencia (itt main kulcsszó), azaz nem tudunk hivatkozni a példányosított osztály többi tulajdonságára.
Az értelmezési zavar onnan származik, hogy túlzás az ilyen jellegű példányosítást névtelennek minősíteni, elvégre van neki neve, például: new Main("Adam"). Továbbá tévedés névtelennek minősíteni csak azért, mert nincsen egyértelműen megszólítható objektumreferenciája (itt main kulcsszó), hiszen ezzel egyúttal azt is állítjuk, hogy a "nevesítés" egyedül ezen objektumreferencián keresztül lehetséges.
Mindettől függetlenül jegyezzük meg ezt a fajta elnevezést, mert programozói szaknyelvben sajnos ez terjedt el. A magam részéről javasolnám a röptében létrehozott osztály definícióját (on-the-fly instantiated class), mert véleményem szerint közelebb áll az igazsághoz.