Vererbung
Klassen können in Java erben und vererben, ähnlich wie bei uns Menschen. Wie das funktioniert erklären wir dir in diesem Beitrag.
Inhaltsübersicht
Hat-Beziehung und Ist-eine-Art-von-Beziehung
Vererbung bei Klassen kannst du dir vorstellen, wie im Tierreich. Die Vererbung setzt verschiedene Klassen in Beziehung zueinander, ähnlich wie Tierarten und Gattungen in der Biologie.
Es gibt 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.
Du siehst: Alle Gruppen, die über eine Ist-eine-Art-von Beziehung verbunden sind, teilen sich gemeinsame Eigenschaften. Schließlich haben Löwen Krallen, genau wie alle anderen Raubkatzen.
Deklarierung der Eigenschaften
Aber wie hilft uns das jetzt in Java weiter?
Diese Art von Vererbung ermöglicht uns, eine hierarchische Ordnung für unsere Klassen festzulegen und reduziert die Menge des redundanten Codes.
Um eine Ist-eine-Art-von-Beziehung zu deklarieren, fügen wir einer deklarierten Klasse diesen Zusatz zu:
Durch das angehängte „extends“, zu Deutsch „erweitert“, tun wir genau das. Unsere neue Klasse übernimmt – also erbt – alle sichtbaren Eigenschaften der Klasse GameObject. Eine Klasse, die durch eine ist-eine-Art-von-Beziehung von einer anderen erbt, nennt man Unterklasse. Die vererbende Klasse hingegen heißt Oberklasse.
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.
Geerbte Eigenschaften einer Klasse können genau so aufgerufen werden, wie in der Klasse selbst deklarierte.
Dabei musst du allerdings darauf achten, dass Eigenschaften, die als private deklariert sind, nicht vererbt werden. Sie sind nicht für andere Klassen sichtbar. 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.
Vererbung bei Konstruktoren nicht möglich
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 Teil einer Klasse ist.
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 solltest du vorher noch wissen.
Auch wenn du einen Konstruktor public oder protected deklarierst, wird dieser nicht vererbt. Das würde auch keinen Sinn machen, da der Konstruktor für z.B. ein Level zu wenig Informationen enthält, um ein Objekt der Klasse Dungeon erzeugen zu können.
Stattdessen ruft Java automatisch bei Ausführung deines neuen Konstruktors als erste Anweisung den „alten“ Konstruktor auf. Diesen Befehl kann man auch manuell einfügen. Das ist aber nur nötig, wenn wir dem Konstruktor Parameter übergeben müssen.
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.
Es kann aber auch sein, dass dir mal eine Eigenschaft einer Oberklasse so gar nicht passt, du aber die restlichen Eigenschaften schon erben willst. Zum Beispiel willst du eine besondere Charakter-Klasse erstellen, deren Charaktere nur zu bestimmten Zeiten erscheinen.
Jetzt kannst du einfach die bereits existierende Methode der Oberklasse Character nehmen und diese umschreiben. Dazu benutzen wir den @Override-Befehl. Nun schreibst du einfach in diese Methode, 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.
Wichtig: Deklarierung der ganzen Klasse als final
Toll! Dein Spiel ist jetzt fertig und du möchtest es veröffentlichen. Aber dafür brauchst du noch einen Log-In für die Spieler. Wenn du diesen programmierst, solltest du allerdings alle sensitiven Eigenschaften oder gleich die ganze Klasse als final deklarieren. Das verhindert, dass die Methode bzw. die ganze Klasse etwas vererbt.
Das klingt jetzt erst mal unpraktisch, aber es verhindert, dass andere deinen Code überschreiben und sich zum Beispiel illegal Zugang zu deiner harten Arbeit verschaffen.
Jetzt ist unser Spiel endlich bereit, um auf den Markt gebracht zu werden und du bist bestens gerüstet, um dein eigenes zu programmieren. Viel Erfolg dabei!