Wozu super() ?

Hallo,

wenn ich mir in eclipse einen Konstruktor erzeugen lasse, dann beginnt der immer mit super();

Mir ist klar dass super() den Standard-Konstruktor der Super-Klasse aufruft. Wenn ich das super() aber wegelasse, wird aber auch der Standard-Konstruktor der Superklasse aufgerufen. Es ist also unnötiger Code. Wo liegt der Sinn dass eclipse ihn trotzdem erzeugt?

viele Grüße
Stefan

Der Konstruktor erwartet manchmal ja auch Parameter, die man der Super-Konstruktor übergeben muss.
Denke deshalb wird er einfach immer erzeugt.
Kann mich aber auch irren.

Lustig. Das Thema habe ich heute in einem anderen Kontext auch schon angeschnitten. Der einzige Sinn, den ich mir darin vorstellen kann ist, dass man damit im Code explizit noch einmal veranschaulicht, dass die Klasse eine andere erweitert (die nicht unbedingt Object heißt) und den Standardkonstruktor verwenden möchte (falls man einen Parameterbehafteten Konstruktor verwendet).

Ansonsten darf der Konstruktoraufruf auch nur als erstes Statement in einem Konstruktor stehen, es lassen sich also keine semantischen Unterschiede durch einen expliziten Aufruf hervorrufen.

Eclipse hat das einfach als Template hinterlegt. Man kann das ganz einfach ausschalten, indem man im Dialog (Generate Constructors from …) den Haken bei “Omit call to default constructor super()” setzt.

Warum muss super() eigentlich als erstes aufgerufen werden?

Ein Grund: Wenn du Attribute in deinem Konstruktor setzt und dann super() aufrufen könntest und würdest, könnten diese Attribute im Superkonstruktor wieder überschrieben werden. So werden erst die Konstruktoren von Object -> DeineKlasse -> DeineErbendeKlasse aufgerufen, z.B…

[QUOTE=Bene]Warum muss super() eigentlich als erstes aufgerufen werden?[/QUOTE]Außerdem willst Du ja im Konstruktor vielleicht auf Konstanten oder Felder aus der Superklasse zugreifen. Dazu müssen die aber erstmal initialisiert sein…

bye
TT

super() findest du ja nunmal in der Vererbung. Zum vererben wird das Schlüsselwort extends verwendet, welches auf Deutsch erweitert bedeutet.

Man erweitert eine Klasse, weil man mehr will, als diese Klasse bietet. Um aber alles, was diese Klasse bietet auch nutzen zu können, muss sie erstmal da sein. Deshalb muss zunächst super() aufgerufen werden, erst dann kann man Erweiterungen vornehmen, in dem man Felder oder Methoden hinzufügt oder auch überschreibt.

p.s.: Wenn du das mit super() verstanden hast. Schau dir am Besten gleich auch this() an, wäre dann ziemlich einfach.

Das mit this ist aber ein ganz anderes Paar Schuhe. Das entspricht eher dem Aufruf eines parametrisierten Elternkonstruktors aus einem Standardkonstruktor heraus.

Das ist mir schon klar. Aber ich denke, wenn man das eine gerade verstanden hat, dann wird man das andere sehr schnell verstehen.

Da verstehe ich dich gerade nicht?!

this() ruft man in einem parametrisierten Konstruktor auf, um zunächst den eigenen Standardkonstruktor abzuarbeiten.

Ok, ich glaube, ich habe da einfach ein wenig verquer gedacht. Für mich war die Logik, dass man super() aus dem parameterlosen Konstruktor aufruft. Die Erweiterung davon ist, dass man aus dem parameterlosen Konstruktor einen parametrisierten Elternkonstruktor aufruft. Aber im Endeffekt hast du recht, so wirklich vergleichbar ist das nicht. Denn man kann die Elternkonstruktoren (ob parametrisiert oder nicht) ja auch aus parametrisierten Konstruktoren aufrufen.
Um um die Verwirrung komplett zu machen, kann man aus dem parameterlosen Kindkonstruktor einen parametrisierten Kindkonstruktor aufrufen, der wiederum einen parametrisierten Elternkonstruktor aufruft der einen anderen… :o)

[QUOTE=cmrudolph]
Um um die Verwirrung komplett zu machen, … :o)[/QUOTE]

Ja, kann man wohl - nie gemacht. Der umgekehrte Weg macht für mich mehr Sinn. Aber egal, für mich ist die Kettenreaktion die man bei Vererbung immer hat (dadurch das alle Klassen Object erweitern) vergleichbar mit der, die man sich mit this() baut. Denn this(), ob ohne oder mit Parametern deutet klar darauf hin, dass es mindestens zwei Konstruktoren hat. Dazu kommt, dass man dort einen Überblick in einer Klasse hat. Aber da wollte ich eigentlich garnicht drauf eingehen, sondern dem TO einen Hinweis geben, denn bei vielen gibt es Verständigungsprobleme bei den Themen this und this(). Und wenn einmal was Klick macht, dann geht noch mehr :wink: Egal, das Internet ist voll damit - ich gönne mir noch etwas Sonne.

Ich rufe eigentlich immer aus dem Parameterlosen Konstruktor den parametrisierten Konstruktor auf. Das hat den Hintergrund, dass es dann nur einen vollwertigen Konstruktor gibt und in allen anderen Konstruktoren nur die this(parameter1, parameter2, ...) Zeile steht, bei der die Parameter ihre Defaultwerte bekommen.

OK, da muss ich ja leider sagen - du hast mich überzeugt :slight_smile:

hallo, danke erstmal für eure antworten.

Vielleicht wr es etwas missverständlich dass ich diese frage im “Grundlagen-Forum” gestellt habe. Mir ist nämlich druchaus klar, was Vererbung, Konstruktoren, this() usw ist. Mir ging es nur darum, dass es keinen unterscheid macht ob ich in einen konstruktor super() schreibe oder gar keinen kostruktor der oberklasse explizit aufrufe. Und ob ich mich vielleicht irre dass es keinen unterschied macht.

viele grüße Stefan

Es macht keinen Unterschied. Wie oben ja auch schon geschrieben, darf der super()-Aufruf nur als erste Anweisung in einem Konstruktor stehen. Und das führt zur selben Ausführungsreihenfolge, wie ohne den expliziten Aufruf.

Ich glaube auch, dass Eclipse das einfügt, damit man leicht noch Parameter ergänzt (und vielleicht auch, damit man es nicht vergisst). Paramaterlose super() aufrufe hab ich auch immer entfernt, wenn Eclipse sie produziert hat (etwa bei Source > generate Constructor using fields).