Problem mit Aufrufreihenfolge bei Vererbung

temi

Top Contributor
Ein gutes neues Jahr!

Ich hab gerade ein vermutlich banales Problem, aber ich finde keine Lösung, die mir gefällt.

Ausgangspunkt ist eine abstrakte Klasse
Java:
public abstract class Parent {

    public Parent() {
        System.out.println("Parent Konstruktor");
        System.out.println(getData());
    }

    protected abstract String getData();
}

Und eine Kindklasse, die durch überschreiben der abstrakten Methode, eine wichtige Information liefern soll, die durch die abstrakte Klasse verarbeitet werden müssen.
Java:
public class Child extends Parent {

    private String data;

    public Child(String data) {
        this.data = data;
    }

    @Override
    protected String getData() {
        return "Child Methode " + data;
    }
}

Java:
    public static void main(String args[]) {
        Child child = new Child("Wichtige Daten");
    }

Geht nur nicht, weil der Parent-Konstruktor vor dem Child-Konstruktor ausgeführt wird. Die überschriebene Methode wird zwar korrekt im Parent-Konstruktor aufgerufen, aber die Daten sind da noch nicht gesetzt und damit null. Ich möchte die Daten nicht in der Methode erzeugen, weil sie von außen (z. B. über den Konstruktor) injiziert werden sollen.

Irgendwie stehe ich gerade auf dem Schlauch. Help!
 
Ein Konstruktor sollte - wegen genau dieser Thematik - generell nie überschreibbare Methoden aufrufen.

Einfach mal aus Effective Java, 3rd Edition, Thema 19:
Es gibt noch ein paar weitere Einschränkungen, die eine Klasse beachten muss, um Vererbung zu ermöglichen. Konstruktoren dürfen keine überschreibbaren Methoden aufrufen, und zwar weder direkt noch indirekt. Ein Verstoß gegen diese Regel führt zu einem Programmabsturz. Der Superklassenkonstruktor wird vor dem Subklassenkonstruktor ausgeführt, sodass die überschreibende Methode in der Subklasse aufgerufen wird, bevor der Konstruktor der Subklasse ausgeführt wurde. Wenn die überschreibende Methode von irgendwelchen Initialisierungen durch den Subklassenkonstruktor abhängt, wird sie sich nicht wie erwartet verhalten.
 
Problem ist gelöst. Meine Parentklasse erbt ebenfalls von einer anderen Klasse und verfügt über eine init() Methode. In dieser erledige ich jetzt das, was der Konstruktor hätte tun sollen.
 
Andere Idee (vielleicht gefällt sie dir ja):

Deine Klasse wird (von außen betrachtet) nicht mit dem Konstruktor, sondern über eine Factory instanziert. Die Factory sorgt dann dafür, daß eine Initialisierungsmethode aufgerufen wird, nachdem das Objekt gebaut ist, aber bevor es endgültig in Verwendung geht.

Edit:
Es muß ja keine eigene Factoryklasse sein. Eine statische Methode reicht ja schon.
 

Zurück
Oben