Öröklődés példa - Torta
Öröklődés¶
Tekintsük az alábbi példát:
public class Torta {
protected int szelet;
private String iz;
public String getIz() {
return iz;
}
public void setIz(String iz) {
this.iz = iz;
}
public Torta(int szelet, String iz) {
this.szelet = szelet;
this.iz = iz;
}
public void info() {
System.out.println("Ez a torta " + this.iz + " ízű, és "
+ this.szelet + " szeletes.");
}
}
Extends, super¶
Ez egy általános torta osztály, tudjuk, hogy egy torta milyen ízű és hány szeletből áll. Tortát bármilyen alkalomra vásárolhatunk, azonban lehetnek speciális alkalmak, amelyek esetében szeretnénk használni a már megírt Torta
osztályunkat, de szeretnénk új, speciálisabb adatokat, metódusokat létrehozni a tortáinknak. Ilyen lehet például egy SzulinapiTorta
osztály, amely torta, de szeretnénk egy új adatot is tárolni, mégpedig a rajta lévő gyertyák darabszámát.
extends
- ezzel a kulcsszóval érhetjük el az öröklődést, az osztály deklarációjában, az osztály neve után kell írnunk, majd az extends
kulcsszó után az ősosztály nevét írjuk.
super
- a gyerekosztályból hivatkozhatunk a szülőre, annak adattagjaira (amiket látunk) és metódusaira is, ezeket super.szuloMetodusanakNeve()
-szerű parancsokkal érhetjük el.
public class SzulinapiTorta extends Torta {
private int gyertyakSzama;
public SzulinapiTorta(int szelet, String iz, int gyertyakSzama) {
super(szelet, iz);
this.gyertyakSzama = gyertyakSzama;
}
public void kivansagotTeljesit() {
System.out.println("Kívánságod teljesült!");
}
public void info() {
System.out.println("Ez a szülinapi torta " + this.getIz() + " ízű, és "
+ this.szelet + " szeletes." + this.gyertyakSzama
+ " db gyertya van rajta");
}
}
A szülő konstruktora pedig egyszerűen a super
kulcsszó metódusként való használatával érhető el, például:
Ha az ősosztály paraméter nélküli konstruktorát szeretnénk meghívni, akkor a super();
hívás a gyermekosztály konstruktorában elhagyható.
Ha nem a default konstruktorát használjuk az ősosztálynak, akkor viszont kötelező a super(arg1,arg2...argn);
meghívása a gyerekosztály konstruktorában!
A gyerekosztályban láthatjuk, hogy az ősből örökölt info()
metódust felüldefiniáltuk (override), annak egy speciálisabb működést adtunk.
Polimorfizmus - Többalakúság¶
A gyerekosztály egy példánya kezelhető a szülő egy példányaként is, egy SzülinapiTorta
objektumot tárolhatunk Torta
példányként is (azaz egy Torta
típusú referenciában), sőt akár egy ős típusú tömbben eltárolhatjuk az ős- és gyerektípusokat vegyesen.
Azonban, ha ős típusként tárolunk egy gyerek típusú objektumot, akkor a gyerek típusú objektum saját osztályában definiált metódusait nem látjuk. Például:
public class TortaMain {
public static void main(String[] args) {
Torta csokiTorta = new SzulinapiTorta(15, "csoki", 9);
csokiTorta.kivansagotTeljesit(); // Ez nem fog működni
}
}
A fenti kódrészlet nem működik, mert az átlagos Torta nem tud kívánságot teljesíteni. Mivel egy Torta
referenciában tároljuk a SzülinapiTorta
objektumot, így csak a Tortában definiált metódusokat használhatjuk! Ennek kiküszöbölésére később látni fogunk egy módszert.
Ugyanígy nem lehetne a gyertyák számát lekérni vagy módosítani sem (még akkor sem, ha public láthatóságú lenne ez az adattag), mert az érintett Torta nem biztos, hogy rendelkezik ilyen adattaggal.
Torta[] cukraszda = new Torta[3];
cukraszda[0] = new Torta(20, "csokis-meggyes");
cukraszda[1] = new Torta(12, "epres");
cukraszda[2] = new SzulinapiTorta(12, "karamell", 12);
Fordításkor még nem tudjuk, hogy a Torta
tömbben milyen típusú objektumok lesznek: Torta
objektumok, vagy pedig SzulinapiTorta
objektumok, esetleg vegyesen, hiszen megtehetjük, hogy egy tömbbe gyerek típusokat teszünk.
Viszont, ha meghívjuk mindegyik elem info()
metódusát, azt látjuk, hogy a sima torták esetében a Torta
osztályban definiált metódus fut le, míg a születésnapi torta esetében a SzulinapiTorta
osztályban definiált info()
metódus hívódik meg.
Ennek oka pedig a kései kötés (late binding). A kései és korai kötésről bővebben itt és itt olvashatsz.
Ennek kimenete:
Ez a torta csokis-meggyes ízű, és 20 szeletes.
Ez a torta epres ízű, és 12 szeletes.
Ez a szülinapi torta karamell ízű, és 12 szeletes. 12 db gyertya van rajta
Ahogy említettük, a gyerek típus kezelhető ősként, viszont ez fordítva nem működik! SzülinapiTorta
tömbbe nem tehetünk ős típusú, azaz sima Torta
objektumokat.