Java-Konstruktorvererbung


Answers

Wenn du von Super ererbst, geschieht das in der Realität:

public class Son extends Super{

  // If you dont declare a constructor of any type, adefault one will appear.
  public Son(){
    // If you dont call any other constructor in the first line a call to super() will be placed instead.
    super();
  }

}

Also, das ist der Grund, weil Sie Ihren einzigartigen Konstruktor aufrufen müssen, da "Super" keinen Standardkonstruktor hat.

Versuchen Sie nun zu erraten, warum Java die Konstruktorvererbung nicht unterstützt, wahrscheinlich weil ein Konstruktor nur Sinn macht, wenn es um konkrete Instanzen geht, und Sie sollten keine Instanz von etwas erstellen können, wenn Sie nicht wissen, wie sie definiert ist (durch Polymorphismus).

Question

Ich habe mich gefragt, warum in Java-Konstruktoren nicht vererbt werden? Du weißt, wenn du eine Klasse wie diese hast:

public class Super {

  public Super(ServiceA serviceA, ServiceB serviceB, ServiceC serviceC){
    this.serviceA = serviceA;
    //etc
  } 

}

Später, wenn Sie von Super erben, wird sich Java beschweren, dass kein Standardkonstruktor definiert ist. Die Lösung ist offensichtlich etwas wie:

public class Son extends Super{

  public Son(ServiceA serviceA, ServiceB serviceB, ServiceC serviceC){
    super(serviceA,serviceB,serviceC);
  }

}

Dieser Code ist repetitiv, nicht TROCKEN und nutzlos (IMHO) ... so dass sich die Frage erneut stellt:

Warum unterstützt Java keine Konstruktorübernahme? Hat es einen Vorteil, diese Vererbung nicht zuzulassen?




Davids Antwort ist richtig. Ich möchte hinzufügen, dass Sie vielleicht ein Zeichen von Gott bekommen, dass Ihr Entwurf versaut ist, und dass "Sohn" keine Unterklasse von "Super" sein sollte, sondern dass Super stattdessen einige Implementierungsdetails am besten zum Ausdruck bringt durch die Funktionalität, die Son bietet, als eine Art Strategie.

EDIT: Jon Skeets Antwort ist am beeindruckendsten.




Im Prinzip erben Sie die Konstruktoren in dem Sinne, dass Sie einfach super aufrufen können, wenn es angemessen ist, es ist nur, dass es fehleranfällig wäre, aus Gründen, die andere erwähnt haben, wenn es standardmäßig passiert ist. Der Compiler kann nicht voraussetzen, wann es angemessen ist und wann nicht.

Die Aufgabe des Compilers ist es, so viel Flexibilität wie möglich zu bieten und gleichzeitig die Komplexität und das Risiko unbeabsichtigter Nebenwirkungen zu reduzieren.




Da Konstruktoren ein Implementierungsdetail sind, können sie von einem Benutzer einer Schnittstelle / Oberklasse überhaupt nicht aufgerufen werden. Wenn sie eine Instanz bekommen, ist sie bereits konstruiert. und umgekehrt, zum Zeitpunkt, an dem Sie ein Objekt konstruieren, gibt es definitionsgemäß keine Variable, der es momentan zugewiesen ist.

Überlegen Sie, was es bedeuten würde, alle Unterklassen zu zwingen, einen geerbten Konstruktor zu haben. Ich argumentiere, dass es klarer ist, die Variablen direkt als für die Klasse zu übergeben, um "magisch" einen Konstruktor mit einer bestimmten Anzahl von Argumenten zu haben, nur weil es Eltern tut.




Eine abgeleitete Klasse ist nicht die gleiche Klasse wie ihre Basisklasse, und es ist vielleicht egal, ob Mitglieder der Basisklasse zum Zeitpunkt der Konstruktion der abgeleiteten Klasse initialisiert werden. Das ist eine Entscheidung, die der Programmierer nicht vom Compiler trifft.