Warum verbietet Java die Vererbung von einer Klasse, deren Konstruktor privat ist?Warum können Sie nicht von einer Klasse erben, deren Konstruktor privat ist?
Antwort
Java verhindert die Unterklassierung von Klassen mit privaten Konstruktoren nicht.
public class Main {
static class A {
private A() {
System.out.println("Subclassed A in "+getClass().getName());
}
}
static class B extends A {
public B() {
}
}
public static void main(String... ignored) {
new B();
}
}
druckt
Subclassed A in Main$B
Was es verhindert ist Unterklassen, die keine Konstrukteure seiner Superklasse zugreifen können. Dies bedeutet, dass ein privater Konstruktor nicht in einer anderen Klassendatei verwendet werden kann und ein lokaler Konstruktor eines Pakets nicht in einem anderen Paket verwendet werden kann.
In dieser Situation ist die einzige Option, die Sie haben, Delegation. Sie müssen eine Factory-Methode aufrufen, um eine Instanz der Klasse "super" zu erstellen und sie zu umbrechen.
etwas ist nicht richtig? eine verschachtelte statische Klasse instanziieren? wie funktioniert es? – Jaxox
@jaxox zum jvm, verschachtelte Klassen sind nichts besonderes. Sie sind wie jede andere Klasse mit einer aber mehr Meta-Informationen. Sie können also eine Klasse erstellen, die auf die gleiche Weise wie jede andere verschachtelt definiert wurde. Btw anonyme Klassen in statischen Methoden sind auch static geschachtelte Klassen. –
@PeterLawrey Ich verstehe, was Sie sagen, aber ich bin immer noch leicht verwirrt. Haben Sie nicht gesagt, dass Java es Unterklassen nicht erlaubt, auf entsprechende Superklassenkonstruktoren zuzugreifen? In Ihrem Beispiel hat Klasse B keinen Zugriff auf den Konstruktor von A. Wie ist das erlaubt? – Grateful
Da eine Klasse mussimmer seine Superklasse Konstruktor aufrufen. Wenn auf den Superklassenkonstruktor nicht zugegriffen werden kann, kann die Unterklasse nicht initialisiert werden.
Weitere Informationen: JLS 8.8.10. Preventing Instantiation of a Class
In Bezug auf Brian Roach Kommentare:
Der Aufruf [zu dem übergeordneten Klasse Konstruktor] ist nur implizit, wenn Sie es nicht tun, explizit und die Eltern haben ein öffentlicher oder geschützter Nicht-Arg-Konstruktor (oder hat keinen definiert, in welchem Fall es einen Standard-Nicht-Arg gibt). Es ist erforderlich, weil ... so funktioniert die Sprache. Kinder [Klassen] müssen [ihren] Elternkonstruktor aufrufen.
Beachten Sie, dass, wenn Sie jede Klasse in Java instanziiert, gibt es immer einen impliziten Aufruf von Object
Konstruktor, da es die Superklasse aller Klassen ist.
public Object() {
}
Vermerk des JLS Link: Sie wird ihre default constructor ausführen
Es ist ein Fehler bei der Kompilierung, wenn ein Standard-Konstruktor implizit deklariert, aber die übergeordnete Klasse nicht über einen zugänglichen Konstruktor (§6.6) das keine Argumente annimmt und keine throws-Klausel hat.
Und warum ist das eine notwendige Bedingung, auch wenn sie implizit ist? – CodeBlue
Wenn die Elternklasse einen privaten Konstruktor deklariert hat, ist nichts implizit. Es würde einen expliziten Aufruf im Child erfordern, aber da der Konstruktor privat ist, können Sie nicht. –
Es gibt einen impliziten Aufruf von super() in jedem Konstruktor, sofern Sie nicht selbst einen angeben. – cogsmos
Wenn der Konstruktor einer Klasse privat ist, kann die untergeordnete Klasse keinen Aufruf an den Superkonstruktor vornehmen. Daher würde die Vererbung fehlschlagen.
Ja, etwas zu Luiggi Antwort diese Funktion von Java-Zugabe verwendet wird, wenn die Singleton-Klassen zu schaffen, das nur eine Instanz dieser Klasse erlaubt geschaffen werden.
Nicht, wenn Sie ein Singleton korrekt erstellen. –
@Brian können Sie mir bitte sagen, wie man es richtig macht, ohne den Konstruktor privat zu machen? –
Josh Bloch, 'Effektive Java zweite Ausgabe' - verwenden Sie eine 'enum'. Siehe: http://stackoverflow.com/questions/5759596/the-best-singleton-pattern-since-java-5. Wenn Sie dieses Buch nicht haben, kaufen Sie es. Es ist ein Muss für jeden, der ernsthaft über Java ist –
Wenn Sie eine Unterklasse haben, haben Sie 2 Möglichkeiten für Kindklasse (Unterklasse): 1. Standardkonstruktor (Kein Argumentkonstruktor): In diesem Fall versucht der Standardkonstruktor automatisch, den Elternklassenkonstruktor aufzurufen: this will fehlgeschlagen, da der Elternklassenkonstruktor privat ist. 2.Parametrisierter Konstruktor: Wenn Sie versuchen, ein Objekt für eine Kindklasse zu erstellen, die den Konstruktor parametrisiert hat, müssen Sie den Elternklassenkonstruktor zwingend vom Kindklassenkonstruktor aus aufrufen, indem Sie Parameter übergeben oder Parameter nicht übergeben: Dies wird auch fehlschlagen, da der Elternkonstruktor privat ist.
Da die untergeordnete Klasse entweder einen Standardkonstruktor oder einen parametrisierten Konstruktor hat und es nicht möglich ist, einen von beiden zu haben, können Sie keine Unterklasse für eine Elternklasse mit privatem Konstruktor haben.
- 1. Warum ist der Konstruktor String() nicht privat?
- 2. Scala-Fall-Klasse privaten Konstruktor ist nicht privat
- 3. Eine Klasse verzieren, deren Konstruktor Parameter hat?
- 4. Konstruktor privat machen
- 5. Warum erlaubt GCC das Erben von einer privaten geschachtelten Klasse?
- 6. warum C# den Konstruktor von Basisklasse nicht
- 7. kann Konstruktor nicht als geschützt oder privat definieren! Warum?
- 8. Warum ist die Hauptmethode privat?
- 9. Wie "erben" Sie einen Iterator von einer STL-Klasse?
- 10. Warum erlaubt GCC das Erben von einer privaten geschachtelten Klasse nicht, wenn Sie ein Freund sind?
- 11. C++ Äußerer Klassenzugriff Innere Klasse ist privat - Warum verboten?
- 12. Warum ist ein privater Konstruktor in einer Singleton-Klasse erforderlich?
- 13. Können Sie eine Methode einer Klasse nicht vererben?
- 14. Erklären Sie, warum es wichtig ist, veränderliche Datenelemente einer Java-Klasse privat zu machen
- 15. Warum ist mein Objekt nicht privat, wenn meine Variable ist?
- 16. std :: is_default_constructible <T> Fehler, wenn Konstruktor privat ist
- 17. Wie können statische Konstruktoren nicht privat gemacht werden?
- 18. Ändern einer Klasse zum Einkapseln statt Erben
- 19. Warum nicht von std :: erben allocator
- 20. C++ Ist privat wirklich privat?
- 21. erben eine statische Klasse
- 22. Dynamisch Auswahl Klasse erben von
- 23. Können in WCF Datenvertragsklassen von einander erben?
- 24. Erteilung einer Referenz auf eine Instanz, deren Konstruktor eine Ausnahme
- 25. Wie kann ich von Rational (oder einer Klasse ohne Konstruktor) erben?
- 26. Können Sie private Funktionen in JavaScript erben?
- 27. Mit privat var von Konstruktor in neue Methode in Javascript
- 28. Frage erben von Liste (von T) Klasse
- 29. Kann eine Ruby-Klassenmethode von einer anderen Klasse erben?
- 30. Warum ist der base() - Konstruktor nicht notwendig?
@HovercraftFullOfEels, siehe Peter Lawreys Antwort. – CodeBlue