5.6 Vererbung Vererbung

Werbung
5.6
Vererbung
• Klassen können zueinander in einer "ist ein"- Beziehung stehen
• Beispiel:
Jeder PKW ist ein Kraftfahrzeug, jedes Kraftfahrzeug ist ein
Transportmittel
aber:
auch jeder LKW ist ein Kraftfahrzeug und
jeder Zug, jedes Schiff und jedes Flugzeug ist ein Transportmittel
Informatik I – Java
© Klaus Hinrichs
5-145
Vererbung
Transportmittel
Kraftfahrzeug
PKW
LKW
SLK 230 A 170
© Klaus Hinrichs
Zug
Schiff
Flugzeug
Multi-Eng.
A 340
Informatik I – Java
B 737
Single-Eng.
C 172 Traveler
5-146
Vererbung
• Sowohl PKWs als auch LKWs besitzen Fahrersitze und Fahrertüren,
es handelt sich also um Attribute der Oberklasse Kraftfahrzeug
• Sowohl PKWs als auch LKWs haben die Methoden Sitz
verstellen,Tür schließen und fahren, es sind Methoden der
Oberklasse Kraftfahrzeug
• PKWs haben jedoch mit der Rückbank und dem Kofferraum eigene
Attribute und mit hinten einsteigen eigene Methoden
• LKWs haben mit der Ladefläche und dem Anhänger auch eigene
Attribute und beladen ist eine eigene Methode
! Unterklassen PKW und LKW besitzen alle Attribute und Methoden
der Oberklasse Kraftfahrzeug, haben jedoch noch zusätzliche
© Klaus Hinrichs
Informatik I – Java
5-147
Ähnlichkeiten bei Objekten
• Zusammenfassen von gleichen Attributen und Methoden
• Beispiel Konten:
Girokonto
kontostand: int
inhaber: Person
habenzinsen: int
sollzinsen: int
dispo: int
holekontostand()
zahle()
© Klaus Hinrichs
Sparkonto
kontostand: int
inhaber: Person
habenzinsen: int
holekontostand()
zahle()
kuendigen()
Informatik I – Java
Festgeldkonto
kontostand: int
inhaber: Person
habenzinsen: int
mindbetrag: int
laufzeit: int
holekontostand()
zahle()
kuendigen()
5-148
Vererbung
• Erweiterung des Klassenmodells:
Konto
kontostand: int
inhaber: Person
habenzinsen: int
holekontostand()
zahle()
Girokonto
sollzinsen: int
dispo: int
© Klaus Hinrichs
Sparkonto
kuendigen()
Festgeldkonto
mindbetrag: int
laufzeit: int
kuendigen()
Informatik I – Java
5-149
Vererbung
• Die vererbende Klasse heißt Superklasse.
• Die erbenden Klassen sind Unter- oder Subklassen.
• Konto ist also die Superklasse der Klassen Girokonto,
Festgeldkonto, Sparkonto. Diese sind die Subklassen der Klasse
Konto.
© Klaus Hinrichs
Informatik I – Java
5-150
Verhältnis zwischen Objekten erbender Klassen
• Alle Objekte sind Konten!
• Einige sind besondere Arten von Konten.
• Die Mengen der Sparkonten, Girokonten, Festgeldkonten sind
jeweils eine Teilmenge der Menge der Konten.
• Die Teilmengen sind disjunkt.
Konto
Sparkonto
Girokonto
Festgeldkonto
© Klaus Hinrichs
Informatik I – Java
5-151
Verhältnis zwischen Objekten erbender Klassen
• Deklarationen:
Girokonto einGirokonto;
Sparkonto einSparkonto;
Konto einKonto, einAnderesKonto;
• Zulässige Zuweisungen:
einGirokonto = new Girokonto();
einSparkonto = new Sparkonto();
einGirokonto.sollzinsen = 12;
einKonto = einGirokonto;
einAnderesKonto = new Sparkonto();
• Nicht erlaubte Zuweisungen:
einSparKonto = einGirokonto;
einGirokonto = new Sparkonto();
© Klaus Hinrichs
Informatik I – Java
5-152
Verhältnis zwischen Objekten erbender Klassen
• Jedes Sparkonto / Girokonto ist auch ein Konto, deshalb ist
einKonto = einSparkonto;
zulässig. Allerdings ist der Zugriff auf alle Attribute nicht möglich,
einKonto kann nur auf die Konto-Attribute zugreifen.
• Ein Objekt einer Klasse kann also mehrere Erscheinungsformen
haben, es kann ein Objekt der Klasse selbst sein oder es kann ein
Objekt einer der Unterklassen dieser Klasse sein. Man nennt es
polymorph.
© Klaus Hinrichs
Informatik I – Java
5-153
Verhältnis zwischen Objekten erbender Klassen
• Was passiert bei folgender Anweisung?
if (x % 2 == 0)
einKonto = einSparkonto;
else
einKonto = einGirokonto;
Der Compiler ist nicht in der Lage, die Klasse von einKonto zu
bestimmen. einKonto kann nach der if-else Anweisung eine von
mehreren Klassen haben, es ist polymorph.
• Ist folgende Anweisung erlaubt?
einKonto = (x % 2 == 0 ? einGirokonto : einSparkonto);
• Nein, da einGirokonto und einSparkonto nicht zuweisungskompatibel sind!
© Klaus Hinrichs
Informatik I – Java
5-154
Die Klasse Konto
public class Konto {
private int kontostand = 0;
private Waehrungsrechner wr;
private Person inhaber;
private int habenzinsen;
public Konto(Person inhaber, Waehrungsrechner wr) {
this.inhaber = inhaber;
this.wr = wr;
}
public void zahle(int pfennige) {
int euroCent = wr.konvInEuroCent(pfennige);
kontostand += euroCent;
}
public int holeKontostand() {
int pfennige = wr.konvInPfennige(kontostand);
return (pfennige);
}
} // Ende der Klasse Konto
© Klaus Hinrichs
Informatik I – Java
5-155
Die Klasse Girokonto
public class Girokonto extends Konto {
private int sollzinsen;
private int dispo;
public Girokonto(Person inhaber, Waehrungsrechner wr) {
super(inhaber, wr);
}
…
} // Ende der Klasse Girokonto
© Klaus Hinrichs
Informatik I – Java
5-156
Technische Aspekte der Vererbung
• Vererbung wird über das Schüsselwort extends realisiert:
class Unterklasse extends Oberklasse {
... // Hier zusätzliche Attribute
... // und Methoden
}
• Die neu definierte Unterklasse erweitert also die anderswo definierte
Oberklasse um neue Attribute und Methoden.
• Alle Methoden und Attribute der Oberklasse werden übernommen.
• Jede Klasse hat genau eine Oberklasse (Java kennt keine
Mehrfachvererbung).
• Ist keine Oberklasse definiert (kein extends), so ist die
Systemklasse Object die Oberklasse " Object ist eine
Oberklasse für alle Klassen (bis auf Object selbst)
• Konstruktoren werden nicht vererbt, Konstruktoren der abgeleiteten
Klasse müssen neu definiert werden!
© Klaus Hinrichs
Informatik I – Java
5-157
Technische Aspekte der Vererbung
• Über das Schlüsselwort super kann am Anfang eines Konstruktors der
abgeleiteten Klasse ein Konstruktor der Oberklasse aufgerufen werden.
• Beispiel:
class A {
A(String name) { ... }
}
class B extends A {
B(String name, int a) {
super(name); // Aufruf des Oberklassenkonstr.
}
}
• Wenn in der ersten Anweisung des Subklassen-Konstruktors nicht einer
der Konstruktoren der Superklasse aufgerufen wird, dann wird der
parameterlose Superklassen-Konstruktor (Standard-Konstruktor)
automatisch aufgerufen, bevor irgendeine andere Anweisung des
Subklassen-Konstruktors aufgerufen wird.
© Klaus Hinrichs
Informatik I – Java
5-158
Zugriffsrechte für Attribute und Methoden
• private Methoden und Attribute sind nur in der Klasse zugreifbar,
in der sie definiert sind.
• protected Methoden und Attribute sind in der Klasse selbst, von
allen Unterklassen und von allen Klassen im gleichen package
zugreifbar.
• Methoden und Attribute ohne Zugriffs-modifikator sind in der Klasse
und von allen Klassen im gleichen package zugreifbar.
• public Methoden und Attribute sind von allen Klassen aus
zugreifbar.
© Klaus Hinrichs
Informatik I – Java
5-159
Überschreiben von Methoden
• Methode berechneZinsen(int tage)
hat gleiche Implementierung in Sparkonto und Festgeldkonto, aber:
in Girokonto Berechnung aus Sollzinsen und Habenzinsen.
Lösung:
Standard-Implementierung in Konto und Überschreiben in Girokonto
public class Konto {
...
protected int berechneZinsen(int tage) { ... }
...
}
public class Girokonto extends Konto {
...
protected int berechneZinsen(int tage) { ... }
...
}
© Klaus Hinrichs
Informatik I – Java
5-160
Zugriff auf überschriebene Attribute / Methoden
• In einem Objekt einer abgeleiteten Klasse ist super eine Referenz
auf das Teilobjekt der Oberklasse, Attribute und Methoden der Oberklasse lassen sich über super ansprechen (auch überschriebene
Attribute und Methoden).
• Beispiel:
class A {
int variable;
void methode() { ... }
}
class B extends A {
int variable;
// Überschreibendes Attr.
void methode() { ... } // Überschreibende Meth.
void methode2() {
super.variable = 3; // Zugriff auf überschriebene
super.methode(); // Attr. und Meth. der Oberklasse
}
}
© Klaus Hinrichs
Informatik I – Java
5-161
Schlüsselwort: final
• final verhindert, daß eine Methode überschrieben wird:
public final int holeKontostand() { ... }
• final verhindert, daß Unterklassen von einer Klasse abgeleitet
werden können:
public final class Girokonto extends Konto { ... }
Von Girokonto können keine weiteren Unterklassen durch Vererbung
abgeleitet werden. Alle Methoden einer finalen Klasse sind implizit auch
final.
• Finale Klassen und Methoden sind manchmal aus Sicherheitsgründen
erforderlich. Sie tun das, was sie tun sollen, und sie können nicht durch
Überschreiben manipuliert werden.
Typische Anwendung: eine Methode zur Passwort-Prüfung.
• final-Variablen können nach ihrer Initialisierung nicht mehr verändert
werden, sie sind also Konstanten:
public final int mwst;
© Klaus Hinrichs
Informatik I – Java
5-162
Abstrakte Methoden / Klassen
• Problem: Jede Subklasse hat die gleiche Methode, aber
unterschiedliche Implementierung.
• Beispiel: public int auszahlen(int betrag);
– Girokonto: beliebige Auszahlung bis Limit
– Sparkonto: Restguthaben von DM 5,- nötig (außer nach Kündigung)
– Festgeld: Auszahlung erst nach Ende der Laufzeit
• Lösung: abstrakte Methode in der Superklasse.
Eine abstrakte Methode ist eine Methode, für die nur eine Signatur
(Kopf der Methode), aber keine Implementierung (kein Rumpf) existiert.
• Enthält eine Klasse eine abstrakte Methode, so ist die Klasse selbst
abstrakt. Es können keine Objekte zu einer abstrakten Klasse erzeugt
werden.
• Eine Unterklasse muß die abstrakten Methoden der Oberklasse
implementieren, oder sie ist selbst wieder abstrakt.
© Klaus Hinrichs
Informatik I – Java
5-163
Beispiel …
public class Datum {
public Datum(int tag, int monat, int jahr) { ...}
public void setzeDatum(int tag, int monat, int jahr)
{ ... }
public static Datum aktuellesDatum() { ... }
public boolean istSpaeterAls(Datum dat) { ...}
public boolean istAbgelaufen() { ...}
public boolean istGleich(Datum dat) { ...}
public int gibDifferenz(Datum dat) { ...}
}
© Klaus Hinrichs
Informatik I – Java
5-164
… Beispiel …
public abstract class Konto {
protected Datum letzteTransaktion;
...
public void einzahlen(int betrag) {
Datum heute = Datum.aktuellesDatum();
int zinstage
= heute.gibDifferenz(letzteTransaktion);
int zinsen = berechneZinsen(zinstage);
zahle(betrag + zinsen);
}
public abstract int auszahlen(int betrag);
}
• Schlüsselwort abstract vor Methode und Klasse!
© Klaus Hinrichs
Informatik I – Java
5-165
… Beispiel
class Girokonto extends Konto {
...
public int auszahlen(int betrag) {
Datum heute = Datum.aktuellesDatum();
int zinstage =
heute.gibDifferenz(letzteTransaktion);
int zinsen = berechneZinsen(zinstage);
zahle(zinsen);
if (kontostand - betrag > dispo) {
zahle(-betrag);
return (betrag);
} else
System.out.println("Keine Auszahlung möglich");
return (0);
}
}
© Klaus Hinrichs
Informatik I – Java
5-166
Polymorphie
• Wunsch:
Alle Objekte aus der Oberklasse Konto sollen in der gleichen Weise
behandelt werden können.
• Lösung:
Eine Oberklassen-Referenz kann auch auf Objekte der Subklassen
verweisen. Methoden der Oberklasse können so aufgerufen werden.
Wurde eine Methode von einer Subklasse überschrieben, so wird
nicht die Methodenimplementierung der Oberklasse aufgerufen,
sondern die Implementierung der Subklasse.
© Klaus Hinrichs
Informatik I – Java
5-167
Polymorphie
• Methoden können so mit allen möglichen Konten arbeiten:
public int berechneVermoegen(Konto[] konten) {
int vermoegen = 0;
for (int i = 0; i < konten.length; i++) {
Konto k = konten[i];
vermoegen += k.holeKontostand();
}
return (vermoegen);
}
• Methodenaufruf wird an die entsprechende Subklasse weitergeleitet
© Klaus Hinrichs
Informatik I – Java
5-168
Technische Aspekte der Polymorphie
• Polymorphie wird bei Vererbung durch Überschreiben der Methoden
der Oberklasse erreicht, dabei muß die Signatur (also Parameterliste
und Rückgabetyp) mit der Methode der Oberklasse übereinstimmen.
• Beim Überschreiben werden die allgemeineren Methoden (der
Oberklasse) durch die konkreteren der Unterklasse überschrieben.
• Auch wenn ein Objekt durch eine Variable eines allgemeineren Typs
referenziert wird, so werden immer die zum Objekt gehörenden
Methoden aufgerufen.
• Überschreiben darf nicht mit Überladen verwechselt werden, bei
überladenen Methoden hat man unterschiedliche Signaturen und nur
der Methodenname ist der gleiche.
© Klaus Hinrichs
Informatik I – Java
5-169
instanceof
• Da jedes Objekt auch über Referenzen der Oberklasse angesprochen
werden kann, ist nicht immer klar, zu welcher Klasse ein Objekt gehört.
Daher gibt es das Schlüsselwort instanceof , um die Klassenzugehörigkeit eines Objektes zu bestimmen:
if(Objektname instanceof Klassenname)
Anweisung;
• Die Abfrage liefert auch dann true, wenn durch Klassenname eine
Oberklasse für das zu Objektname zugehörige Objekt angegeben
wird.
© Klaus Hinrichs
Informatik I – Java
5-170
Beispiel: Klasse X
public abstract class X {
private int a;
public X() { this.a = 0; }
public X(int a) {
if (a >= 0) this.a = a; else this.a = 0;
}
protected void set(int a) {
if (a >= 0) this.a = a; else this.a = 0;
}
protected int geta() {
return a;
}
public abstract void print();
}
© Klaus Hinrichs
Informatik I – Java
5-171
Beispiel: Klasse Y
public class Y extends X {
private int b;
public Y(int a, int b) { super(a); this.b = b; }
public Y() { this(0, 0); }
public void set(int a, int b) {
set(a);
this.b = b;
}
protected int getb() { return b; }
public void print() {
System.out.println("In Y: a = " + geta()
+ " b = " + b);
}
}
© Klaus Hinrichs
Informatik I – Java
5-172
Beispiel: Klasse Z
public final class Z extends Y {
private int c;
public Z(int a, int b, int c) {
super(a, b);
this.c = c;
}
public Z() { this(0, 0, 0); }
public void set(int a, int b, int c) {
super.set(a, b);
this.c = c;
}
public void print() {
System.out.println("In Z: a = " + geta()
+ " b = " + getb() + " c = " + c);
}
}
© Klaus Hinrichs
Informatik I – Java
5-173
Beispiel: Klasse Test
public class Test {
public static void main(String args[]) {
System.out.println("Beginn Test");
Y y = new Y(1, 1);
Z z = new Z(2, 2, 2);
X x;
y.print(); // In Y: a = 1 b = 1
z.print(); // In Z: a = 2 b = 2 c = 2
x = y;
// x.set(3, 3); ist nicht erlaubt!
x.set(3);
x.print(); // In Y: a = 3 b = 1
x = z;
// x.set(3, 3); ist nicht erlaubt!
// x.set(3, 3, 3); ist nicht erlaubt!
x.print(); // In Z: a = 2 b = 2 c = 2
Y y1 = z; // y1.set(4, 4, 4); ist nicht erlaubt!
y1.set(5, 5);
y1.print(); // In Z: a = 5 b = 5 c = 2
System.out.println("Ende");
}
}
© Klaus Hinrichs
Informatik I – Java
5-174
Herunterladen