Gyakorlati alapok III.
Öröklődés (inheritance)
Abstract osztály - abstract metódus
Az előző fejezetből megértettük a specializálódás műveletének osztályszerkezetekre gyakorolt hatását. Segítségével egy logikusan felépített és jól továbbalakítható (osztály)hierarchia alakítható ki. Elméletileg nézve ennek tetején a lehető legáltalánosabb definíciójú osztály áll, amely már csak „filozófiai magasságokban” lévő, teljesen vagy részlegesen absztrakt elemeket tartalmaz. Pontosan ez a cél, mert –képszerű céges hasonlattal-, a céghierarchia legtetején lévő főnök csakis stratégiai irányelveket határoz meg.
A Java nyelv ezt az abstract módosítószó beépítésével is támogatja. Az így megjelölt osztály (nagy valószínűséggel) a hierarchia legtetején áll (legalábbis ez lehet az alkotó programozó szándéka) és a new paranccsal nem példányosítható (azaz nem lehet létrehozni belőle objektumot), ebből következően csakis örökítő célokat szolgál. Nézzük erre konkrét kódpéldákat!
A Sikidom osztály fogalmilag elég absztraktnak tűnik ahhoz, hogy ezzel a kulcsszóval illessük. Ha jobban belegondolunk, egy síkidomnak csakis 2 olyan tulajdonsága lehet, amely aztán minden további síkidomra jellemző, ez pedig a terület és kerület, ezért getter-setter függvények formájában ezeket építjük be:
public class
Sikidom {
private double kerulet;
private double terulet;
public void setKerulet(double kerulet) {
if (kerulet < 0) {
System.out.println("Az érték nem lehet negatív!");
} else {
this.kerulet
= kerulet;
}
}
public void setTerulet(double terulet) {
if (terulet < 0) {
System.out.println("Az érték nem lehet negatív!");
} else {
this.terulet
= terulet;
}
}
public double getKerulet() {
return this.kerulet;
}
public double getTerulet() {
return this.terulet;
}
public static void main(String[] args) {
Sikidom sikidom = new Sikidom();
System.out.println(sikidom.toString());
}
}
Végeredmény:
Sikidom@15db9742
A toString() metódus segítségével az objektum
szöveges reprezentációját kaptuk meg (erről részletesen
Az Ős, mely sokasodni foszlik: az Object osztály
című fejezetben olvashatunk). Ezzel sokat nem mondtunk, a példányosításnak sok
értelme nem volt, de látható, hogy legalább "él" az objektumunk. Az
abstract módosítás azonban le fogja tiltani a
példányosítást:
public abstract
class Sikidom {
private double kerulet;
private double terulet;
public void setKerulet(double kerulet) {
if (kerulet < 0) {
System.out.println("Az érték nem lehet negatív!");
} else {
this.kerulet
= kerulet;
}
}
public void setTerulet(double terulet) {
if (terulet < 0) {
System.out.println("Az érték nem lehet negatív!");
} else {
this.terulet
= terulet;
}
}
public double getKerulet() {
return this.kerulet;
}
public double getTerulet() {
return this.terulet;
}
public static void main(String[] args) {
Sikidom sikidom = new Sikidom();
}
}
Végeredmény:
Cannot instantiate the type Sikidom
Egy nagyobb projekt beindításakor gyakran előfordulhat, hogy a tervező szoftvermérnök megalkotja a teljesen vagy részlegesen absztrakt osztályokat és azok származtatásos kidolgozását már a csapat más tagjaira bízza.
Az abstract módosításnak további hatásai is vannak:
-
abstract osztálynak bármennyi abstract metódusa lehet, de ha ilyet tartalmaz, akkor kötelezően az osztálynak is abstract-nak kell lennie; mindemellett tetszőleges mennyiségben tartalmazhat nem abstract metódusokat is,
-
az abstract metódusnak csak metódusfeje van, nincs műveleti blokkja, például:
public abstract class Sikidom{
public double hossz;
public abstract double kerulet();
public abstract double terulet();
}
-
abstract osztályból öröklődéssel létre lehet hozni további abstract osztályokat, de ennek nincs sok értelme, ha azonban a származtatott osztály nem abstract és benne abstract metódusok találhatók, azok mindegyikét ki kell dolgozni,
-
Az Ami a változót (és a többieket) változatlanná teszi: a final című fejezetben volt először szó a final módosítószóról. Benne ezt olvashatjuk: a final class Valami{} azt jelenti, hogy nem örökíthető, nem terjeszthető ki (extends), azaz belőle utódosztályok nem származtathatók. Mivel az abstract osztály és metódus csakis örökítési célokat szolgál és a final éppen ezt gátolja, abstract osztály és metódus nem lehet egyúttal final is.