Super() - Wann und wieso notwendig?

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

Super() - Wann und wieso notwendig?
Hallo,

angenommen, man hat zwei Klassen Eltern und Kind, wobei Kind von Eltern erbt.

public class Eltern {
	public Eltern(int a) {
	
	}
}
public class Kind extends Eltern {
	public Kind() {
		
	}
}

Wieso kommt es zu einer Fehlermeldung und warum muss die super()-Anweisung in den Konstrukter von Kind?

    public Kind() {
		super(0);
	}

Kurz: Wenn die Vater-Klasse, von der geerbt wird, (in diesem Fall [m]Eltern[/m]) keinen Standardkonstruktor besitzt, muss in jedem Konstruktor der Kind-Klasse angegeben werden, welcher Konstruktor der Vater-Klasse benutzt werden soll - dazu benutzt man das Schlüsselwort [m]super[/m].

Ausführlich: Wenn eine Klasse B von einer anderen Klasse A erbt (also [m]B extends A[/m]), dann besitzt ein Objekt der Kind-Klasse B erstmal alle Attribute und Methoden der Vaterklasse. Außerdem besitzt es natürlich noch weitere Attribute und Methoden, die man erst in der Klasse B (also [m]class B extends A { /* hier */ }[/m]) definiert.
Das sieht dann so aus:

Objekt der Klasse A:
- Attribute aus A
- Methoden aus A
- wird initialisiert mit: Konstruktoren für A

Objekt der Klasse B (extends A):
- Attribute aus A
- Methoden aus A
- Attribute aus B
- Methoden aus B
- wird initialisiert mit: Konstruktoren für B

Falls Klasse A nun keinen Standardkonstruktor ([m]public A()[/m]) besitzt, wäre ein Objekt der Klasse B natürlich nicht vollständig initialisiert, da ein Konstruktor der Klasse B sich ja nur um die Initialisierung der Attribute aus Klasse B kümmern kann. Wäre in Klasse A implizit oder explizit ein Standardkonstruktor vorhanden, würde dieser einfach implizit vor dem Aufruf des jeweils angegebenen Klasse-B-Konstruktors aufgerufen werden.
Wenn man also folgende Situation hat …

class A {
    public A() { ... }
}
class B extends A {
    public B() { ... }
}

… und man mit [m]new B()[/m] ein Objekt der Klasse B erstellt, wird dabei implizit zuerst der Konstruktor in A aufgerufen.
Ist allerdings kein Standardkonstruktor in A vorhanden, musst du einen mit dem [m]super[/m]-Befehl angeben, damit bekannt ist, welcher A-Konstruktor bei der Initialisierung eines Objekts der Klasse B zuvor ausgeführt werden soll, um den A-Teil des Objekts zu initialisieren. Da dieser Konstruktor der Vater-Klasse immer zuerst aufgerufen wird, muss [m]super [/m]auch die erste Zeile im Konstruktor sein. [m]super [/m]ruft quasi den Konstruktor der Vater-Klasse auf - natürlich jeweils denjenigen, je nachdem, wie die Parameter angegeben sind (Stichwort: Überladung).

1 Like

Sehr vielen Dank. Die Antwort ist sehr gut und hat alle meine Fragen beantwortet :slight_smile: