Java Standard: Vererbung
Die sogenannte Vererbung ermöglicht es Informationen (Variablen) und Verhalten (Methoden / Operationen) weiterzugeben. Dies ist eine wesentliche Möglichkeit um Redundanz zu vermeiden. Die Erben fügen dann weitere Informationen und/oder Verhalten hinzu. Zwei Klassen stehen dabei zueinander als Superklasse (Erblasser) und Subklasse (Erbe) in Beziehung.
Vererbung ist ein zentrales Thema in der objektorientierten Programmierung (OOP) - siehe auch w:Objektorientierte Programmierung.
Erzeugen und Zerstören von Subklassen
BearbeitenDas Erzeugen und Zerstören von Subklassen erfolgt analog zu einer normalen Klasse. Intern werden jedoch auch die Standardkonstruktoren der jeweiligen Superklasse beim Erzeugen und analog die finalize Methode beim Zerstören aufgerufen. Dies ist wichtig, da wir die Informationen und das Verhalten der Superklasse verwenden. Evtl. Grundstellen der Informationen oder Aufräumarbeiten beim Zerstören unserer Instanz sind somit auch bei den ererbten Informationen notwendig.
Überschreiben von Methoden
BearbeitenIn der Subklasse können Methoden der Basisklasse "überschrieben" werden. Damit wird der Inhalt der ursprünglichen Methode verändert.
package org.wikibooks.de.javakurs.oo;
public class MeineKlasse
{
// Nun der Konstruktor
public MeineKlasse ()
{
//...
}
//ursprüngliche Methode
public methode()
{
System.out.println("Wir sind in der Basisklasse");
}
}
public class MeineSubklasse extends MeineKlasse
{
public methode()
{
System.out.println("Wir sind in der Subklasse");
}
}
Wird die methode()
-Methode für ein Objekt des Typs MeineSubklasse
aufgerufen, wird der Satz "Wir sind in der Subklasse" ausgegeben.
Überschriebene Methoden werden für die Anwendung der Laufzeit-Polymorphie in Java benötigt. Dabei werden Methoden erst zur Laufzeit (im Gegensatz zur Compile-Zeit) den Objekten zugeordnet.
Anmerkung: Im Deutschen wird das Verb "überschreiben" benutzt. Im Englischen heißt es jedoch "override", nicht "overwrite".
Mit dem JDK 1.6 / Java 6 sollte die zudem eine Annotation (Anmerkung) angebracht werden:
...
public class MeineSubklasse extends MeineKlasse
{
@Override
public methode()
{
System.out.println("Wir sind in der Subklasse");
}
}
...
Javaspezifische Implementierung
BearbeitenIn Java sind alle Objekte von der Klasse Object abgeleitet. Object ist somit die Basisklasse von allen anderen Klassen. Alle Klassen sind Subklassen von Object.
Man leitet eine eigene Klasse von der Basisklasse durch extends ab:
public class Beispiel extends Object
{
//...
}
static
BearbeitenAls static
-deklarierte Elemente gehören keinem Objekt an, sondern der Klasse (oder Schnittstelle), in der sie definiert sind. Das berühmteste Beispiel ist hier
public static void main(String[] args)
{
//...
}
Die main-Methode muss als static
deklariert sein, da vor ihrem Aufrufen ja kein Objekt instanziiert sein kann.
Als static
können sowohl Variablen als auch Methoden deklariert werden.
Da static
-Methoden von allen Objekten unabhängig sind, haben sie Einschränkungen:
- Es können aus ihnen heraus nur andere
static
-Methoden aufgerufen werden. - Sie können auch nur auf
static
-Variablen zugreifen. static
-Methoden und -Variablen können nicht mitthis
odersuper
angesprochen werden.
abstract
BearbeitenAls abstract
-deklarierte Methoden werden in der Basisklasse nur deklariert. Die Definition findet dann in den Subklassen statt.
abstract class BeispielKlasse
{
abstract void schreibIrgendwas();
}
class BeispielSubklasse extends BeispielKlasse
{
void schreibIrgendwas()
{
System.out.println("Irgendwas");
}
}
In der Basisklasse wird nur angegeben, dass die Methode existiert, aber nicht wie sie implementiert ist. Damit wird also zugesichert, dass jedes Objekt des Typs BeispielKlasse
- und damit auch jedes Objekt einer davon abgeleiteten Klasse - die Methode schreibIrgendwas()
besitzen muss.
In BeispielSubklasse
muss die abstrakte Methode daher implementiert werden, ansonsten gibt es einen Compilerfehler. Wird eine abstrakte Methode in einer Unterklasse nicht implementiert, so muss diese Klasse selbst auch wiederum als abstract
gekennzeichnet werden.
Generell muss jede Klasse, die mindestens eine abstrakte Methode enthält, auch selbst als abstrakt deklariert werden. Dies hat den Effekt, dass keine Objekte direkt von dieser Klasse erstellt werden können. Im obigen Beispiel wäre es also nicht zulässig, ein Objekt der Klasse BeispielKlasse
mit
new BeispielKlasse();
zu erzeugen.
final
BearbeitenDurch die Benutzung von final
kann das Ableiten einer Klasse oder Überschreiben einer Methode verhindert werden.
final class BeispielKlasse
{
void schreibIrgendwas()
{
//...
}
}
class BeispielSubklasse extends BeispielKlasse
{
//...
}
Das funktioniert nicht. Durch das final
-Schlüsselwort kann von der Klasse Beispielklasse
nicht abgeleitet werden.
class BeispielKlasse
{
final void schreibIrgendwas()
{
//...
}
}
class BeispielSubklasse extends BeispielKlasse
{
void schreibIrgendwas(){
//...
}
}
Hier wird zwar die Subklasse erstellt, jedoch kann die Methode schreibIrgendwas()
nicht überschrieben werden.
super
BearbeitenUm den Konstruktor der Basisklasse aufzurufen, wird die Methode super()
verwendet. Sie wird im Konstruktor der Subklasse verwendet. super()
wird benutzt, um private
-Elemente der Basisklasse anzusprechen.
class Beispiel extends Object
{
protected variable;
Beispiel()
{
super();
variable = 10;
}
}
super()
ruft hier den Konstruktor von Beispiel auf, und könnte somit private
-Elemente manipulieren.
Als zweite Anwendungsmöglichkeit kann super
im Zusammenhang mit einem Element der Basisklasse benutzt werden.
super.methodeABC();
super.variableXYZ;
Durch diese Aufrufe werden aus der Subklasse heraus die Methoden/ Variablen der Basisklasse aufgerufen.
Einfluss von Modifizierern auf die Vererbung
Bearbeitenpublic und protected
BearbeitenSowohl public- wie auch protected-Elemente werden an die abgeleitete Klasse vererbt. An ihrem public bzw. protected-Status ändert sich nichts.
public methode();
protected variable;
private
BearbeitenPrivate-Elemente werden nicht vererbt.
private variable;
packagevisible
BearbeitenDies ist der voreingestellte Modifizierer, der angewandet wird, wenn kein anderer Modifizierer angegeben wird. Durch ihn können nur Objekte aus dem gleichen Paket auf die Elemente zugreifen.
class Beispielsklasse
{
//...
}
Er wird ohne Einschränkungen an die Subklasse vererbt.