Java osztály készítése, adattagok, és metódusok, láthatóság, konstruktor, destruktor. Objektum létrehozása, használata, öröklés. ( Előfeltétel 12. Tétel ) Az osztály egy olyan típus leíró struktúra, amely tartalmaz adattagokat és metódusokat, amelyek segítségével az adattagokon műveleteket végezhetünk. Az osztályt, mint típust új objektumok definiálására használjuk, hogy azzal további műveleteket végezzünk. Emellett maximálisan támogatja az öröklődést, a polimorfizmust(virtuális függvények) és az egységbezárást, amik az objektum orientált programozás alapkövei. Egy osztálydefiníció egy új típust hoz létre,. Az osztály használatához létre kell hozni a típushoz tartozó objektumot. Ezt nevezzük az osztály példányának. Az osztály objektumát a beépített típusokba tartozó változókhoz hasonlóan vehetjük fel. Másik megoldással, ha dinamikusan akarjuk létrehozni, akkor a new operátorral tehetjük ezt meg. A delete operátorra itt nincs szükség, mivel az automatikus szemétgyűjtésnek köszönhetően a már nem használt dinamikusan lefoglalt memóriát a java automatikusan felszabadítja. A Java minden new operátorral lefoglalt memóriaterületről referenciaszámlálót vezet, azaz területenként számolja rá a hivatkozó referenciákat. Amikor új hivatkozás van az objektumra, akkor megnöveli a számlálót, amikor a hivatkozás megszűnik, akkor csökkenti. Amikor már nincs hivatkozás több, akkor felszabadítja a lefoglalt memóriaterületet. Ez az automatikus szemétgyűjtés. Figyelem ez nem azt jelenti, hogy a felszabadításnál minden osztályon belüli objektum törlődik, ez csak részben igaz. Helyette lehetőségünk van protected void finalize() funkciót írni, ami az objektum megsemmisülése előtt lefut , és a megmaradt saját dinamikusan létrehozott objektumainkat eltakarítja a memóriából. A tagokat a . operátorral érhetjük el a C vagy C++ struktúrák elemeihez hasonlóan. Az osztály tagjainak elérhetőségét a protected, public és private hozzáférés módos1tókkal állíthatjuk be. Alapértelmezésként minden osztályon belüli tag, ha külön nem adjuk meg private-nak minősül. Az egységbezárás: ua. C++. A konstruktor: ua. C++. A destruktor: nincs. Automatikus szemétgyűjtés + finalize funkció. Tagfüggvényeken belül a this: ua. C++. A static kulcsszó: ua., mint C++, csak Java-ra vetítve. Ugyanarra használjuk, mint C++ - ban, csak más szintaktikával. Pelda öröklődésre: import java.io.*; import java.text.*; import java.util.*; import extra.*; class CEmberek { private static String m_cNev; protected int iCounter; public CEmberek() { iCounter++; System.out.print("CEmberek " + m_cNev + " letrejottem, Counterem: " + iCounter + "\n"); } public CEmberek(String sparam) { iCounter++; m_cNev = sparam; System.out.print("CEmberek " + m_cNev + " letrejottem, Counterem: " + iCounter + "\n"); } public void SetNev(String sparam) { m_cNev = sparam; } public String GetNev() { return m_cNev; } }; class CProgramozo extends CEmberek { public CProgramozo() { iCounter++; System.out.print("CProgramozo " + GetNev() + " letrejottem, Counterem: " + iCounter + "\n"); } public CProgramozo(String sparam) { super(sparam); iCounter++; SetNev(sparam); System.out.print("CProgramozo " + GetNev() + " letrejottem, Counterem: " + iCounter + "\n");
1
} }; public class Main extends CProgramozo { public Main() { iCounter++; System.out.print("Main " + GetNev() + " letrejottem, Counterem: " + iCounter + "\n"); } public Main(String sparam) { super(sparam); iCounter++; SetNev(sparam); System.out.print("Main " + GetNev() + " letrejottem, Counterem: " + iCounter + "\n"); } public static void main(String[] args) { Main foprogram = new Main(); Main foprogram2 = new Main("Attila"); } } Kimenet: CEmberek null letrejottem, Counterem: 1 CProgramozo null letrejottem, Counterem: 2 Main null letrejottem, Counterem: 3 CEmberek Attila letrejottem, Counterem: 1 CProgramozo Attila letrejottem, Counterem: 2 Main Attila letrejottem, Counterem: 3 Most nézzünk példát a szemétgyűjtésre ugyanezzel a példaprogrammal, csak kiegészítjük egy finalize függvénnyel a Chair osztályt. Most a Chair osztály működése a lényeg. import import import import
java.io.*; java.text.*; java.util.*; extra.*;
class CEmberek { private static String m_cNev; protected int iCounter; public CEmberek() { iCounter++; System.out.print("CEmberek " + m_cNev + " letrejottem, Counterem: " + iCounter + "\n"); } public CEmberek(String sparam) { iCounter++; m_cNev = sparam; System.out.print("CEmberek " + m_cNev + " letrejottem, Counterem: " + iCounter + "\n"); } public void SetNev(String sparam) { m_cNev = sparam; } public String GetNev() { return m_cNev; } }; class CProgramozo extends CEmberek { public CProgramozo() { iCounter++; System.out.print("CProgramozo " + GetNev() + " letrejottem, Counterem: " + iCounter + "\n"); } public CProgramozo(String sparam) { super(sparam); iCounter++; SetNev(sparam); System.out.print("CProgramozo " + GetNev() + " letrejottem, Counterem: " + iCounter + "\n"); } };
2
class Chair { static boolean gcrun = false; static boolean f = false; static int created = 0; static int finalized = 0; int i; Chair() { i = ++created; if(created == 47) { System.out.println("Létrehozva 47"); f = true; } } protected void finalize() { if(!gcrun) { gcrun = true; System.out.println("finalize kezdődik miután " + created + " Szék létrejött"); } if(i == 47) { System.out.println("finalize folyamatban Chair #47, " + "Itt már nem kreálunk több széket."); } finalized++; if(finalized >= created) System.out.println("Minden " + finalized + " felszabadult"); } } public class Main extends CProgramozo { public Main() { iCounter++; System.out.print("Main " + GetNev() + " letrejottem, Counterem: " + iCounter + "\n"); } public Main(String sparam) { super(sparam); iCounter++; SetNev(sparam); System.out.print("Main " + GetNev() + " letrejottem, Counterem: " + iCounter + "\n"); } public static void main(String[] args) { Main foprogram = new Main(); Main foprogram2 = new Main("Attila"); boolean bElotte = false; System.out.println("Most szívjuk a memóriát"); while(!Chair.f) new Chair(); if( bElotte ) { System.out.println("garbagecollection():"); System.gc(); System.out.println("runFinalization():"); System.runFinalization(); } if(!bElotte) System.runFinalizersOnExit(true); System.out.println ( "Miután minden szék létre lett hozva:\n" + "összes létrejött = " + Chair.created + ", összes finalize = " + Chair.finalized); System.out.println("viszlát!");
} } Kimenet: CEmberek null letrejottem, Counterem: 1 CProgramozo null letrejottem, Counterem: 2 Main null letrejottem, Counterem: 3 CEmberek Attila letrejottem, Counterem: 1 CProgramozo Attila letrejottem, Counterem: 2 Main Attila letrejottem, Counterem: 3 Most szívjuk a memóriát Létrehozva 47 Miután minden szék létre lett hozva: összes létrejött = 47, összes finalize = 0 viszlát!
3
finalize kezdődik miután 47 Szék létrejött finalize folyamatban Chair #47, Itt már nem kreálunk több széket. Minden 47 felszabadult Kimenet, ha a boolean bElotte = true: CEmberek null letrejottem, Counterem: 1 CProgramozo null letrejottem, Counterem: 2 Main null letrejottem, Counterem: 3 CEmberek Attila letrejottem, Counterem: 1 CProgramozo Attila letrejottem, Counterem: 2 Main Attila letrejottem, Counterem: 3 Most szívjuk a memóriát Létrehozva 47 garbagecollection(): finalize kezdődik miután 47 Szék létrejött finalize folyamatban Chair #47, Itt már nem kreálunk több széket. Minden 47 felszabadult runFinalization(): Miután minden szék létre lett hozva: összes létrejött = 47, összes finalize = 47 viszlát! Egy meglévő osztályból újat származtathatunk azáltal, hogy a meglévő osztály nevét feltüntetjük az új osztály deklarációjában. A már meglévő osztályt ősosztálynak, az új osztályt származtatott osztálynak nevezzük. Csak itt extends a neve a dolognak, nem COsztály : public Ősosztály. A származtatott osztály örökli az ősosztály minden tagját, a származtatott osztályt új tagokkal láthatjuk el (változók, függvények). A származtatott osztály konstruktora explicit módon inicializálhatja az ősosztályát azáltal, hogy paramétereket ad át az ősosztály konstruktorának. Ha a származtatott osztály konstruktora expliciten nem inicializálja az ősosztály konstruktorát, akkor a fordító automatikusan az ősosztály konstruktorát hívja meg. Lásd super kulcsszó használata a fenti példákban. A származtatott osztályok hierarchiájában minden osztály adott tagfüggvényének saját változatával rendelkezhet. Ha ez a függvény virtuális is egyben, akkor ennek meghívásakor mindig az aktuális objektum típusának megfelelő változat fog lefutni, még akkor, ha a hívás egy ősosztályra mutató mutatón keresztül történik. A virtuális függvények a polimorfizmus is támogatják, azaz egyetlen utasítás segítségével több, művelet futhat le, és hogy éppen melyik, az a szóban forgó objektum típusától függ.
különféle
A virtuális függvények segítségével egyszerű, általános célú rutinok írhatóak, amelyek különböző, de egymással kapcsolatban álló objektumok széles választékát tudják kezelni. A virtuális függvények segítségével továbbá lehetőség van az ősosztály viselkedésének módosítására anélkül, hogy a forráskódon módosítanánk. Amikor a származtatunk, akkor a kód megkettőzése és a lehetséges egyéb redundanciák elkerülése cél. A virtuális függvények az objektum orientált programozás egy fontos vonását támogatják, a polimorfizmust(többalakúság). Akkor beszélünk többalakúságról, ha egyetlen utasítással többfajta különböző művelet hajtható végre, és az, hogy éppen melyik, attól függ, hogy éppen melyik objektumról van szó. Az öröklés előnyei:ua. C++. import java.io.*; import java.text.*; import java.util.*; import extra.*;
class CEmberek { private static String m_cNev; protected int iCounter; public CEmberek() { iCounter++; System.out.print("CEmberek " + m_cNev + " letrejottem, Counterem: " + iCounter + "\n"); }
public CEmberek(String sparam) { iCounter++; m_cNev = sparam;
4
System.out.print("CEmberek " + m_cNev + " letrejottem, Counterem: " + iCounter + "\n"); }
public void SetNev(String sparam) { m_cNev = sparam; }
public String GetNev() { return m_cNev; }
public void Azonosit() { System.out.print("En CEmberek vagyok\n"); } };
class CProgramozo extends CEmberek { public CProgramozo() { iCounter++; System.out.print("CProgramozo " + GetNev() + " letrejottem, Counterem: " + iCounter + "\n"); }
public CProgramozo(String sparam) { super(sparam); iCounter++; SetNev(sparam); System.out.print("CProgramozo " + GetNev() + " letrejottem, Counterem: " + iCounter + "\n"); } public void Azonosit() { System.out.print("En CProgramozo vagyok\n"); } };
public class Main extends CProgramozo { public Main() { iCounter++; System.out.print("Main " + GetNev() + " letrejottem, Counterem: " + iCounter + "\n"); }
public Main(String sparam)
5
{ super(sparam); iCounter++; SetNev(sparam); System.out.print("Main " + GetNev() + " letrejottem, Counterem: " + iCounter + "\n"); } public void Azonosit() { System.out.print("En Main vagyok\n"); }
public static void main(String[] args) { Main foprogram = new Main(); foprogram.Azonosit(); Main foprogram2 = new Main("Attila"); foprogram2.Azonosit(); } } Kimenet: CEmberek null letrejottem, Counterem: 1 CProgramozo null letrejottem, Counterem: 2 Main null letrejottem, Counterem: 3 En Main vagyok CEmberek Attila letrejottem, Counterem: 1 CProgramozo Attila letrejottem, Counterem: 2 Main Attila letrejottem, Counterem: 3 En Main vagyok
6