Java: A klassz osztály |
Bevezetőként tisztázzuk
a következőket: Önnek, kedves olvasónak, aki ezt a cikket olvassa
rendelkeznie kell bizonyos Java programozási alapokkal, tehát ne ez legyen az
első cikk, amit a Java nyelvről olvas el. Másodsorban, szándékaim
szerint ez egy több részes cikksorozat lesz, mely felboncolja a Java által
nyújtott alacsony színtű objektumkezelési metódusokat. Ez a cikk
bevezetőként szolgál, megmutatja az előttünk álló lehetőségeket,
és felvet egy érdekes problémát is, mégpedig a dinamikus osztálybetöltés
problémáját. Az elkövetkező cikkek még mélyebbre fognak ásni ebben a
témakörben. Sok sikert, és kitartást. |
Miről
is van szó? |
Valószínűleg sokan Önök
közül nem tudják, hogy mire is lehet használni a Java-ban az egyik
alaposztályt, amely a "fantáziadús" Class névre
hallgat. Igazuk is van, ez nem igazán a leghasználtabb (és legismertebb)
osztály, viszont egy cikksorozatot megérdemel, mert sok érdekesség rejlik e
mögött az egyszerű név mögött, és egy pár probléma megoldását igencsak
elősegíti ezeknek a rejtett tulajdonságoknak az ismerete. Viszont mielőtt
beleugranánk a mélyvízbe, tisztáznunk kell egy alapvető fogalmat. Mi a
különbség egy osztály, és az osztály egy példánya között. Az osztály egy absztrakt
fogalom, a példánya pedig egy objektum, mely tartalmazza az osztály
metódusait, illetve tulajdonságait. Vegyük például a következő
egyszerű kódrészletet: class Test { public Test() { System.out.println("Test Constructor"); } public static void main(String[]
args) { Test test =
new Test(); } } Ebben az esetben a Test nem más,
mint az osztály. A testObj változó (mert valójában ő egy változó) pedig egy
objektum, melyet Test osztály alapján hoztunk létre. Ennek az objektumnak
van memóriacíme, elfoglal bizonyos számú bájtot ettől a címtől
kezdődően, és tudunk hivatkozni rá és a függvényeire, illetve a
tulajdonságaira. Vele ellentétbe, az osztályának nincs elérhető címe, és
az osztály semmiképp nem kezelhető úgy, mint egy objektum, hiszen nem
az. Ez egy absztrakt fogalom, és az objektumok, melyek belőle
származnak, a konkrét példányai. Hiába vannak egy osztálynak tulajdonságai,
ha nem tudunk hivatkozni rájuk, hiszen azok valójában csak a példányosított
objektumokban jelennek meg. Viszont egy osztályról jó tudni, hogy milyen
tulajdonságai vannak, hogy tudjuk, hogy az objektumokban mit használunk. Nem kell persze
elfeledkeznünk a statikus (osztály) metódusokról, illetve a statikus
tulajdonságokról se, de ezek tárgyalása nem tartozik ebbe a cikkre. Ennyi bevezető
után vágjunk is bele. |
Dinamikus
betöltések |
Amint ki lehetett találni
ennyiből, a Java Class osztály pont a fent bemutatott absztrakt fogalmat
próbálja kézzelfoghatóvá tenni. Ha elkezdjük böngészni a Java API-t, az
első dolog, ami a szemünkbe ötlik, az az, hogy ennek az osztálynak nincs
konstruktor függvénye. Erre figyelmeztet az is, hogy a Class osztály
példányai akkor jönnek létre, amikor új objektumokat hozunk létre a new
paranccsal, vagy valamilyen más módon. A dinamikus betöltés alapja
az, hogy futó alkalmazásban dinamikusan választjuk ki az osztályt, amelyet be
akarunk tölteni, és abból példányosítunk egy objektumot. Erre persze rengeteg
mód van, és a legtöbb egy sok mérföldes if (haladó
programozóknak meg switch) listában merül ki. A Class osztály
szolgál egy nagyon elegáns megoldással, amit ebben a cikksorozatban
szándékomban áll bemutatni. Ez teljesen kiküszöböli a többmérföldes if-eket, és
még a fránya new kulcsszót se kell agyonnyúzni. Most szerintem felkapta a
fejét a kedves Olvasó. Milyen más módszerrel lehet még objektumokat
létrehozni. Hát például lehet használni a Class osztály newInstance() metodusát.
Ez nem csinál mást, mint az említett osztály alapján létrehoz egy darab
objektumot. Vagyis példányosítja az osztályt. Annak érdekében, hogy még
világosabb legyen, amit mondani szeretnék, meghívja az osztálynak a
konstruktor függvényét. Egy probléma adódik ezzel a
módszerrel, mégpedig, hogy hogyan kapunk mi olyan objektumot, mely Class típusú
osztály példánya? Természetesen minden objektumnak van egy olyan metódusa,
hogy getClass(), amely visszatéríti az osztályt, melynek az objektum a
példánya, de ez kevés és nem is igazán érdekes, hisz egy létező,
általunk létrehozott objektumról igazán illik tudni, hogy milyen osztály
alapján hoztuk létre. Másként állunk hozzá a
dolgokhoz, ha megvizsgáljuk az osztály (a Class osztály) forName(String) metódusát.
A Java API-jának leírásából kiderül, hogy ez a metódus tálcán felszolgálja
nekünk azt az osztályt, aminek a nevét paraméterben megadtunk. Figyelem! Ne keverjük a
dolgokat: A Class osztály is csak egy osztály. Viszont a Class osztály
egy példánya egy olyan objektum, mely más osztályokat jelképez. Ez alatt a
következőt érthetjük: a Class osztály egy példányából létre tudunk hozni egy olyan
objektumot, mely olyan típusú mint a Class osztály példánya. Térjünk vissza a Class osztály forName(String)
függvényéhez. Amint mondtam, ez visszaadja azt az osztályt, amelynek a nevét
megadtuk a paraméterben. Ha egészen véletlenül melléparamétereztünk, akkor
szép Exceptionokat dob. Például egy ClassNotFoundException
megmondja, hogy nem talált ilyen nevű osztályt. Ennél a pontnál már van egy
darab osztályunk, tehát nem kell mást tennünk, mint meghívni a Class osztály newInstance()
metódusát. És ezzel már kész is lennénk, hisz ennek a metódusnak a
visszatérési értéke egy objektum, melyet a mi Class
osztályunkból példányosított. A forráskód így néz ki: class Test2 { public Test2() { System.out.println("Test Constructor"); } public static void main(String[]
args) { try { Test2 test =
(Test2)Class.forName("Test2").newInstance(); } catch (Exception ex)
{ ex.printStackTrace(); } } } Akad a megoldásnak egy kis
hátulütője. Ez a metódus csak akkor működik tökéletesen, ha az
osztálynak olyan konstruktora van, amely nem vár el paramétert a hívótól.
Másképp szép Exception-ök sorozatát adja vissza. Hogy ezt hogy lehet
áthidalni, majd a következő részben fogjuk letisztázni, ahol
bővebben megismerkedünk egy pár, igencsak szép és hasznos osztállyal, és
egyéb ízletes ínyencségek várnak még ránk. |
Deák Ferenc |