Java Vererbung
In diesem Beitrag erklären wir dir die Vererbung in Java. Dabei lernst du das Konzept dahinter kennen und wie du Klassen in Beziehungen zueinander setzt.
Du möchtest die Java Vererbung schnell verstehen und anwenden können? Dann schau dir unbedingt unser Video dazu an!
Inhaltsübersicht
Java Vererbung einfach erklärt
Du kannst dir die Vererbung von Klassen in Java vorstellen wie im Tierreich. Die Vererbung setzt verschiedene Klassen in Beziehung zueinander, ähnlich wie Tierarten und Gattungen in der Biologie.
Dabei unterscheidet man verschiedene Beziehungen. Zum einen die Hat-Beziehung und zum anderen die Ist-eine-Art-von–Beziehung.
Ein Beispiel für eine Hat-Beziehung wäre eine Katze. Eine Katze HAT vier Beine. Ein Beispiel für eine Ist-eine-Art-von–Beziehung wären Raubkatzen. Löwen sind eine Art von Raubkatzen.
Wie du erkennen kannst, teilen sich alle Gruppen, die über eine Ist-eine-Art-von-Beziehung verbunden sind, gemeinsame Eigenschaften. Schließlich haben Löwen Krallen, genau wie alle anderen Raubkatzen. Jetzt weißt du schon, wie das Prinzip der Java Vererbung funktioniert. Aber schauen wir uns einmal an, was du damit machen kannst.
Vererbung in Java mit extends
Die Vererbung in Java ermöglicht es dir eine hierarchische Ordnung für Klassen festzulegen und reduziert somit die Menge des redundanten Codes. Das bedeutet, dass du die Attribute und Methoden einer Klasse vererben kannst und du sie damit nicht nocheinmal programmieren musst.
Gehen wir einmal davon aus, du hast eine Klasse GameObject
und möchtest nun eine Klasse Level
programmieren, welche die Attribute und Eigenschaften der Klasse GameObject
erbt. Um das in Java umzusetzen schreibst du dann einfach hinter Level
das Schlüsselwort extends
und anschließend die Klasse von der Level
erben soll. In unserem Fall also GameObject.
Durch das angehängte extends
(erweitert), erweiterst du sozusagen die Klasse GameObject.
Unsere neue Klasse Level
übernimmt – also erbt – alle sichtbaren Eigenschaften der Klasse GameObject
.
Ganz allgemein ist es also so, wenn du möchtest, dass eine Klasse mit dem Namen Name2
von einer Klasse mit dem Namen Name1
erben soll, dann erreichst du das in Java durch extends
class Name2 extends Name1{
//Attribute und Methoden
}
Unterklasse und Oberklasse in der Java Vererbung
Eine Klasse, die durch eine ist-eine-Art-von-Beziehung von einer anderen Klasse erbt, nennt man Unterklasse. Die vererbende Klasse hingegen heißt Oberklasse. In unserem oberen Beispiel wäre also Level
eine Unterklasse von GameObject
und GameObject
dementsprechend eine Oberklasse von Level
.
Da die Vererbung hierarchisch geordnet ist, ist sie auch transitiv. Das heißt, wenn Level eine Unterklasse von GameObject
ist und Dungeon
eine Unterklasse von Level
, dann ist auch Dungeon
eine Unterklasse von GameObject
.
Wichtig ist hier noch zu wissen, dass Java – im Gegensatz zu anderen Programmiersprachen – keine Mehrfachverebung erlaubt. Eine Klasse kann also immer nur direkt von genau einer anderen Klasse erben.
Auf geerbte Attribute und Methoden zugreifen
Auf geerbte Eigenschaften einer Oberklasse kannst du auch in der Unterklasse wie gewohnt zugreifen. Du musst jedoch darauf achten, dass du eventuell nicht auf alle Eigenschaften zugreifen kannst. Das hängt davon ab, wie welchem Modifier du deine Eigenschaften in der Oberklasse deklariert hast. Hier musst du zwischen private
, public
und protected
unterscheiden.
Hast du in der Oberklasse eine Eigenschaft mit private
deklariert, dann kann diese nicht vererbt werden. Sie sind nicht für andere Klassen sichtbar. Deshalb kannst du auf diese in der Unterklasse auch nicht zugreifen. Um jetzt nicht alle deine Eigenschaften public
deklarieren zu müssen, kannst du auf die sogenannte protected
Deklaration umsteigen. Diese ermöglicht die Vererbung der Eigenschaften an Unterklassen inner- und außerhalb des Pakets, macht die Eigenschaften aber nur für Nicht-Unterklassen im selben Paket sichtbar.
Es kann aber auch sein, dass du nicht alle Eigenschaft von der Oberklasse erben möchtest. Dazu gibt es den @Override
Befehl. Damit kannst du Methoden überschreiben. In die neue Methode schreibst du dann einfach, was statt des ursprünglichen Verhaltens getan werden soll. Du kannst aber immer noch die ursprüngliche Methode der Oberklasse aufrufen, indem du ein super
davorsetzt. Schauen wir uns dazu ein Beispiel an. Angenommen du hast eine Klasse Eltern
und eine Klasse Baby
. Da die Eltern im Gegensatz zum Baby schon sprechen gelernt haben, wird die Begrüßung unteschiedlich aussehen. Aber auch das Baby gibt einen Laut von sich, wenn jemand kommt. Das sieht dann wie folgt aus:
public class Eltern{
//Attribute
public void begruessen(){
System.out.println("Guten Tag!");
}
//Weitere Methoden
}
Das heißt die Eltern begrüßen mit Guten Tag!
. Da das Baby aber nicht guten Tag sagen kann, aber von der Klasse Eltern erben soll, müssen wir die Methode begruessen()
mit dem @Override
überschreiben und dementsprechend anpassen
public class Baby extends Eltern{
//Attribute
@Override
public void begruessen(){
System.out.println("Ahhhh");
}
//Weitere Methoden
}
Überblick behalten mit instanceof
Aber selbst, wenn du einmal den Überblick verlieren solltest, welches Objekt zu welcher Klasse gehört, bist du nicht aufgeschmissen. Du kannst ganz einfach mit dem instanceof
Befehl überprüfen, ob ein Objekt objekt
zu einer Klasse NameKlasse
gehört
objekt instanceof NameKlasse
Aber Vorsicht! Diese Anweisung gibt auch einen wahren Wert zurück, wenn die angegebene Klasse eine Oberklasse der gesuchten Klasse ist.
Jetzt kannst du schon fast alles, was du brauchst, um deine eigene Vererbungs-Hierarchie anzulegen, aber eine Sache müssen wir uns noch genauer anschauen. Was passiert bei der Java Vererbung mit Konstruktoren?
Java Vererbung bei Konstruktoren
In Java können Konstruktoren nicht vererbt werden. Auch wenn du einen Konstruktor public
oder protected
deklarierst, wird dieser nicht vererbt. Stattdessen ruft Java automatisch bei Ausführung des Konstruktors der Unterklasse als erste Anweisung den Konstruktor der Oberklasse auf. Dies erfolgt mit mit dem Schlüsselwort super()
. Diesen Befehl kann man auch manuell einfügen. Das ist aber nur nötig, wenn wir dem Konstruktor der Oberklasse Parameter übergeben müssen. Schauen wir uns dazu ein Beispiel an. Angenommen die Klasse GameObject
hat folgende Gestalt,
public class GameObject{
public String tier;
public GameObject(String tname){
tier = tname;
}
//Weitere Methoden
}
dann kannst du diesen Konstruktor aus der Unterklasse Level
wie folgt aufrufen
public class Level extends GameObject{
private int level;
public Level(String tier, int lv){
super(tier); //Hier wird der Konstruktor der Oberklasse aufgerufen
level = lv;
}
//Weitere Methoden
}
Zudem musst du vorsichtig sein, wenn du this
und super
im selben Konstruktor verwenden willst. Beide Operationen sind nämlich nur gültig, wenn sie die erste Anweisung sind. Um das zu umgehen, kannst du die Anweisung, die this
enthält, in eine eigene Funktion auslagern.
Java Vererbung Schlüsselwort final
Schauen wir uns zum Abschluss noch an, was das Schlüsselwort final
in Bezug auf die Java Vererbung bewirkt. Setzt du anstelle von public
das Schlüsselwort final
, so kann die Klasse nicht abgeleitet werden. Damit du kannst du also angeben, dass eine Klasse nichts vererben soll.