Professional Documents
Culture Documents
03 Java
03 Java
Inicializálás és takarítás z
– Eltakarítás hiánya
C++ óta: Konstruktor
– Garantált inicializálás objektum létrejöttekor
– Helyette lehetne initialize(), de ezt mindig
kézzel kellene meghívni
– Neve = az osztály neve
class Rock {
– Java-ban nincs Rock() {
destruktor! }
System.out.println("Creating Rock");
Konstruktor Constructor
Operáció-kiterjesztés Overloading
z Mint minden más függvénynek, a z Magasabb szintű nyelvekben
konstruktornak is lehetnek paraméterei: neveket használunk
– Megadják, hogyan inicializáljunk z Természetes nyelvben is lehet több értelme a
Tree t = new Tree(12);
szavaknak:
– Szövegkörnyezetből derül ki az értelme
– Csak úgy lehet létrehozni, hogy megadjuk a
z Programozásban ezt nevezzük overloading-nak vagy
magasságot is
kiterjesztés-nek (túlterhelés ☺)
z Konstruktornak nincs visszatérési értéke – (Overriding = felüldefiniálás, ld. később)
– Objektumra való referenciát kapunk z Régebben pl. C-ben minden név egyedi volt (nincs
printf int-re meg float-ra külön-külön)
Megkülönböztetés this
z Hogyan különböztetjük meg, hogy melyik kiterjesztett z Egy függvény kódja csak egy példányban van a
metódus hívódjon? memóriában
z A paraméterlistáknak egyedieknek kell lenniük Class Banana { void f(int i) {/*…*/} }
z Hívás helyén az aktuális argumentumok típusai Banana a = new Banana(), b = new Banana();
a.f(1);
határozzák meg (ld. korai kötés) b.f(2);
z Konvertálható primitív típusoknál bonyolultabb a z Honnan tudja az f(), hogy melyik objektumhoz lett
helyzet: hívva?
– Ha nincs pontos egyezés, akkor az adat konvertálódik
(de csak nagyobb típusokra!) z Egy „titkos” implicit első paramétert generál a fordító
z Függvény visszatérési értéke nem használható a
megkülönböztetésre (lehetetlen is lenne):
– Pl. f(); hívásnál a vissz. érték nincs is használva
Rendszerfejlesztés előadás fóliák Rendszerfejlesztés előadás fóliák
2002. 03. 18. 74 2002. 03. 18. 75
© Ferenc Rudolf © Ferenc Rudolf
this (folyt.) Kitakarítás Cleanup
z Mire jó? Amikor valamire explicite fel akarjuk z Nem csak a korrekt inicializálás fontos,
használni, pl.: hanem az erőforrások helyes kezelése is
– Ha a metódus formális paraméterneve megegyezik z Java: garbage collector (ez csak memóriával
valamelyik mező nevével: foglalkozik)
z Nem minden takarítást tud elvégezni:
this.x = x; // az első az attribútum
– new nélküli memóriafoglalás (pl. natív metódus által)
– Visszaadni egy metódussal: – Egyéb esetben nincs rá szükség mert minden Object
leszármazott el lesz takarítva
class Leaf {
int i = 0;
Leaf increment() { i++; return this; }
z Segítség: finalize()
}
/* ... */ x.increment().increment(); – Takarítás előtt hívódik
– Nem destruktor!
Rendszerfejlesztés előadás fóliák Rendszerfejlesztés előadás fóliák
2002. 03. 18. 76 2002. 03. 18. 77
© Ferenc Rudolf © Ferenc Rudolf
– Pl. még sok szabad memória van és elkerülhető a z Működés: több algoritmus szerint, de ez mind
fölösleges lassítása a programnak
rejtve marad:
– Kiszámíthatatlan, hogy mikor fog hívódni
– Pl. referenciaszámlálás
z Tehát, ez nem azonos a destruktor szerepével:
– Fontos, hogy mindig végrehajtandó feladatot ne
rakjunk a finalize()-ba (pl. fájl lezárás)
– Definíció helyén
c2 = new C(2);
}
– Instance initialization clause A() { i = 2; } // default konstruktorral
// előbb 1, utána 2
– Konstruktorral: az előző kettő után hívódik csak }
A(int i) { this.i = i; }
– Méretet nem lehet megadni (akkor foglalódik le amikor z Biztonságos, mert túlindexelésnél nincs elszállás,
inicializáljuk) hanem kivétel lesz dobva
– Deklaráláskor csak egy referenciánk van a tömbre
z Ezek az extra funkcionalitások lassíthatják a
z Inicializálás (helyfoglalás) programot
– Inicializáló kifejezéssel: int[] a1 = { 1, 3, 4 };
z Inicializálás futás közben (méret nem ismert előre):
– Tömb másolással: int[] a2 = a1;
int i;
– Lefoglalt terület elemei 0-ra lesznek inicializálva i = /* ??? */;
int[] a1 = new int[i];
z Többdimenziós tömbök:
– Hasonló az egydim.-hoz int[][] a2d = { {1,2,3}, {4,5,6} };
– Explicite ki kell írni a csomag nevét az osztály elé – Ha nincs kiírva, akkor alapértelmezett a “friendly”
Friendly (vagy “package access”):
– Csomagon belül minden osztály eléri (public)
– Csomagon kívül nem elérhető (private)
– Szorosan kapcsolódó osztályokat lehet így
csoportosítani (egymást használják)
Rendszerfejlesztés előadás fóliák Rendszerfejlesztés előadás fóliák
2002. 03. 18. 92 2002. 03. 18. 93
© Ferenc Rudolf © Ferenc Rudolf
Újrafelhasználhatóság Reuse
OOP programozás (és a Java nyelv) egyik
legvonzóbb tulajdonsága a kód hatékony
újrafelhasználásának lehetősége
Osztályok újrafelhasználása De: újrafelhasználás ≠ egyszerű másolás
Régebbi nyelvekben próbálkozás a
procedurális programozás
Ennél jobb az osztály újrafelhasználása:
– Ne kelljen minden osztályt újból megírni, hanem
építőkockaként felhasználni a meglévőket
Rendszerfejlesztés előadás fóliák Rendszerfejlesztés előadás fóliák
2002. 03. 18. 98 2002. 03. 18. 99
© Ferenc Rudolf © Ferenc Rudolf
Újrafelhasználhatóság (folyt.) Kompozíció Composition
A lényeg: mindezt úgy csinálni, hogy a Kompozíció: összetétel, Aggregation
meglévő kódot (osztályokat) ne módosítsuk aggregáció, rész-egész kapcsolat
Kompozíció: új osztályban meglévő Egy osztály egy mezője (adattagja) másik
osztályokból készítünk objektumot osztály típusú (vagy primitív) az egy
Öröklődés: kompozíció (összetett osztály):
– Új osztály létrehozása egy meglévő „altípusaként” – S inicializálva lesz null-ra
– Új funkcionalitás hozzáadásával – i 0-ra class A {
private String s;
OOP-nek
Rendszerfejlesztés előadás fóliák Rendszerfejlesztés előadás fóliák
2002. 03. 18. 100 2002. 03. 18. 101
© Ferenc Rudolf © Ferenc Rudolf
Öröklődés Inheritance
Öröklődés (folyt.)
class Cleanser { /* ... */
z Minden OOP nyelvnek szerves része public void scrub() {} Detergent d;
public void apply() {}
z Java-ban minden új osztály implicite örököltetve van } d.apply();
d.scrub();
az Object-ből (direkt, vagy indirekt módon) public class Detergent extends Cleanser { d.foam();
// metódus módosítása (felüldefiniálás):
z Új osztály származtatása meglévőből: „olyan mint a public void scrub() { super.scrub(); /* ... */ }
// új metódus hozzáadása:
régi”: public void foam() {}
}
– Bővíti azt (extends kulcsszó)
z Az ősnek van néhány interfész metódusa (public)
– A származtatott az ős minden adatát és metódusát
„megkapja” – örökli az őstől z A származtatott ezeket mind tartalmazza, tehát az interfész újra
fel van használva
z Az öröklődés: z scrub() felüldefiniálja az ősét (specializálja a viselkedését):
– Származtatott (al-, gyermek-osztály) szempontjából – Overriding
specializálás – Őst is hívhatja super segítségével (egyébként rekurzív lenne)
– Ős szempontjából (alap-, szülő-osztály) általánosítás z foam() új metódus, bővítése az ősnek
Rendszerfejlesztés előadás fóliák Rendszerfejlesztés előadás fóliák
2002. 03. 18. 102 2002. 03. 18. 103
© Ferenc Rudolf © Ferenc Rudolf
Ős osztály inicializálása Ős inicializálása (folyt.)
z Öröklődés nem csak az osztály interfészét „másolja”
Ha nem default az ős konstruktor, hanem
z A származtatottból létrejövő objektum vannak argumentumai, akkor kézzel kell
rész-objektuma lesz az ősnek!
meghívni a super segítségével:
– Ős objektum ugyanolyan marad + körül van véve a
class Game {
származtatott új elemeivel ős Game(int i) { /* ... */ }