Vererbung von Java Klassen verhindern, verbieten, ausschließen: So gehts
Man kann die ganze Java Vererbung für bestimmte Klassen ausschließen bzw. verhindern oder verbieten.
Was soll das?
Für bestimmte Java Klassen soll die Vererbung ausgeschlossen werden.
Es soll also verhindert werden, dass Elternklassen – Kindklassen bekommen können.
Klingt ein bisschen wie Verhütung, oder?
Denn wie auch im echten Leben, können Kinder zu kleinen Tyrannen werden.
Sie bedienen sich der elterlichen Ressourcen und machen damit was sie wollen.
Wo soll das nur enden?
Nun stell dir mal folgendes vor:
Du hast eine Klasse Tier und diese Klasse hat weitere Unterklassen zum Beispiel Pferd.
Das Pferd hat wiederum Unterklassen für Haflinger, Ponys oder Przewalski-Pferde.
Irgendwann muss doch auch mal Schluss sein.
Nach dem Przewalski-Pferd – was soll da noch kommen?
Eine Unterklasse, wie kleines und großes Przewalski-Pferd macht keinen Sinn.
Hier endet diese Vererbungslinie also.
Jede weitere Kindklasse von dieser Pferdeart würde das Programm nicht verbessern.
Ganz im Gegenteil – Es würde das Programm nur noch verschlechtern, es unnütz aufblähen und unverständlich machen.
Du, als Entwickler, so eines Pferdeprogrammes solltest darauf achten, dass du die Vererbungslinie irgendwann einmal enden lässt.
Inhalt
- 1 Denn die Superklassen kennen ihre Kinder nicht.
- 2 Nicht öffentliche Klassen verhindern die Vererbung für ganz bestimmte Klassen.
- 3 Die zweite Möglichkeit die Vererbung in Java zu verbieten – läuft über den Konstruktor.
- 4 Die beste Lösung um in Java Vererbung zu verhindern, bietet das Keywort final.
- 5 Zusammenfassung:
Denn die Superklassen kennen ihre Kinder nicht.
Das einfache Setzen des Keywort extends reicht völlig aus.
Und schwuppdiwupp sind die Super- oder Oberklassen stolze Eltern.
Aus einer ganz allgemeinen Klasse „Tier“, wird die speziellere Kindklasse „Pferd“.
So wie hier.
public class Tier {
int alter; //Alter des Tieres
int groesse;//Größe des Tieres
int anzahlBeine;//Anzahl der Beine
}
Und die Klasse Pferd erbt von Tier.
public class Pferd extends Tier{
}
Und diese Kindklasse kann dann einfach die Variablen zur Größe, zum Alter oder zur Anzahl-der-Beine übernehmen.
Frechheit, oder?
Wenn du dann eine Programmstartklasse mit main-Methode anlegen würdest, könntest du dort die Kindobjekte erzeugen.
Und dieses neue Kindobjekt hätte Zugriff auf alle Instanzvariablen der Elternklasse.
public class ProgrammStart {
public static void main(String[] args) {
Pferd pferdEins = new Pferd ();//neues Pferd-Objekt
pferdEins.alter=12;//Pferd hat ein Alter von 12
pferdEins.groesse=122;//Pferd hat eine Größe von 122 cm
pferdEins.anzahlBeine=4;//Pferd hat vier Beine
}
}
Krass oder?
Hier das Bild dazu.
Das Schlimmste dabei ist, dass die Elternklassen dies gar nicht mitbekommen.
Sie wissen nicht einmal, dass sie Kinder haben.
Die Kindklassen kennen ihre Eltern schon.
Denn schließlich erweitern sie die Elternklassen ganz bewusst, durch den Zusatz extends.
Unfair, oder?
Damit muss Schluss sein.
Wir leben schließlich im 21. Jahrhundert, sind aufgeklärt worden und kennen die Möglichkeit zur Verhütung.
Also sind hier drei Möglichkeiten, wie du die Vererbungsmöglichkeiten für Klassen eindeutig verhindern kannst.
Nicht öffentliche Klassen verhindern die Vererbung für ganz bestimmte Klassen.
Öffentliche Klassen sind mit dem Keywort public ausgezeichnet.
Unsere beiden Klassen „Tier“ und „Pferd“ sind ebenfalls public-Klassen.
Ich lege jetzt einmal eine weitere Klasse, namens „Hund“ für speziellere Pferde an.
Blöd oder?
Aber theoretisch möglich.
Das Pferd hätte nicht einmal ein Mitbestimmungsrecht.
Ich lege jetzt drei Packages an.
Eines für Hunde, eines für Pferde und eines für allgemeine Tiere.
Und verschiebe dann per Drag and drop die Klassen in die Packages.
Durch das verschieben passiert so Einiges.
- In allen Klassen befinden sich danach die package-Importe ganz oben.
- Da die Tierklasse sich jetzt in einem neuen package befinden – kann die Programmstartklasse nicht mehr auf die Instanzvariablen der Tierklasse zugreifen.
- Du musst also die Instanzvariablen auch als public anbieten.
Und was passiert noch?
Hund erbt immer noch von einem Pferd.
Alles bis hierher war nur die Vorbereitung – das Warm Up.
Jetzt kommt das Entscheidende.
Mach einmal die Klasse „Pferd“ nicht explizit öffentlich.
Streiche also das Keywort public.
Und jetzt ist es für den Hund unmöglich ein Pferd zu sein.
Das bedeutet jetzt für Dich:
Eine Klasse kann nur von einer anderen package-fremden Klasse erben, wenn diese public ist.
Von einer nicht-public oder nicht-öffentlichen Klasse können nur innerhalb des gleichen Package – Kindklassen gebildet werden.
Aber….
Dies ist sehr ungewöhnlich und auch nicht der beste Weg, um in Java Vererbung zu verhindern.
Die zweite Möglichkeit die Vererbung in Java zu verbieten – läuft über den Konstruktor.
Und zwar kannst du in der Superklasse einen privaten default-Konstruktor anbieten.
Somit wird das einfache Erstellen eines neuen Objektes nicht möglich.
Und die Kindklasse, welche sich auf den Konstruktor der Superklasse beruht – kann diesen ebenfalls nicht nutzen.
Aber auch diese Lösung ist suboptimal.
Die beste Lösung um in Java Vererbung zu verhindern, bietet das Keywort final.
Stichwort sind finale Klassen.
Diese können nicht überschrieben werden.
package pferdepackage;
import tierpackage.Tier;
public final class Pferd extends Tier{
}
Sobald du eine Klasse als final kennzeichnest, ist eine Erweiterung durch Unterklassen ausgeschlossen.
Und dies ist die herkömmliche Lösung.
Diese finale-Klassen-Lösung solltest du eigentlich immer nutzen.
Und deshalb….
Nur wenn du dir wirklich irgendetwas besonderes dabei denkst, nutze die beiden anderen Lösungen.
Zusammenfassung:
- Es macht immer Sinn den Ausstieg zu planen.
An irgendeiner Stelle ist immer Schluss mit Vererbung. - Einen noch spezielleren Typen einer Klasse gibt es dann nicht mehr bzw. es macht keinen Sinn dies anzubieten.
Und deshalb solltest du in Java Vererbung auch verhindern bzw. verbieten.
Nicht gänzlich.
Du solltest nur einige bestimmte Klassen von der Java Vererbung ausschließen. - Dabei stehen dir drei Möglichkeiten zur Verfügung. Neben privaten Konstruktoren, nicht-öffentlichen Klassen in fremden Packages – bietet es sich an, Klassen mit dem Modifier final auszuzeichen.