2016-04-28 4 views
1

ich die folgenden Klassen:Java abstrakt Eltern Aufruf Kind Methode vor Kind in Mutter Konstruktor initialisiert

abstract class Parent 
{ 
    private ClassDependentOnSize classDependentOnSize; 

    public Parent() 
    { 
     this.classDependentOnSize = new ClassDependentOnSize(size()); 
    } 

    public abstract int size(); 
} 

class Child extends Parent 
{ 
    private String DBSelection; 
    private String[] DBSelectionArgs; 

    public Child (String selection, String... selectionArgs) 
    { 
     super(); 
     this.DBSelection = selection; 
     this.DBSelectionArgs = selectionArgs; 
    } 

    @Override 
    public int size() 
    { 
     //FAILS because Parent calls size before DBSelectionArgs is initialized 
     String temp = ""; 
     for(String str : DBSelectionArgs) 
      temp += str; 
     return temp.length; 

     //This function basically does a calculation that should not be 
     //done before hand. I have posted the exact method below. 
    } 
} 

class ClassDependentOnSize 
{ 
    public ClassDependentOnSize(int size) 
    { 

    } 
} 

Während diese sind nicht meine genaue Klasse, das ist das gleiche Problem. Ich habe dieses geschrieben, um den unnötigen Code zu entfernen.

Wie Sie sehen können, versucht die Superklasse size() aufzurufen, bevor das untergeordnete Element fertig initialisiert wird, um die Klasse abhängig von der Größe zu erstellen. Ich bin gespannt wie jemand das in der Vergangenheit gelöst hat. Wie alle sicher wissen, muss super() die erste Zeile in einem Kindkonstruktor sein. Wie ich diese Klassen gelegt habe, ist das ein schlechtes Design? Ich habe das Gefühl, dass dies ein Problem ist, das vorher passiert sein muss, aber ich kann keine Lösung finden.

EDIT: Hier ist die genaue Methode. Es wird für eine Android-Anwendung verwendet.

+0

Siehe http://stackoverflow.com/questions/18138397/calling-method-from-constructor – djmorton

+0

@khelwood Ich denke, du meinst overridable, nicht überlastet – ControlAltDel

+0

@ControlAltDel Ganz richtig. – khelwood

Antwort

1

Eine einfache Lösung für Ihren speziellen Fall besteht darin, die Größe als Argument an den übergeordneten Konstruktor zu übergeben.

Dies setzt natürlich voraus, dass Ihr reales Problem die gleichen Eigenschaften aufweist, nämlich dass alle Informationen, die der Basisklassenkonstruktor benötigt, beim Aufruf des Konstruktors verfügbar sind.

+0

Ja, aber Originalplakat sagt, das ist nicht sein/ihr * exaktes * Problem – ControlAltDel

+0

ControlAltDel ist korrekt, ich kann die Größe nicht vorher bestimmen, da sie in der Größenmethode berechnet wird. Ich kann meine Frage aktualisieren, aber der Code wird komplexer. –

1

Ich hatte definitiv dieses Problem vorher. Die Mitnehmen Lektion ist, dass Sie nie nicht-private Methoden in der übergeordneten Konstruktor aufrufen sollte, so hat dieser Elternteil nicht passieren

+0

Es sei denn, sie sind endgültig – djmorton

+0

@djmorton wahr! – ControlAltDel

+0

Technisch ruft der Elternteil eine abstrakte Methode auf, die im Kind implementiert ist, aber ich sehe was du sagst. Gibt es eine gemeinsame Arbeit? –

1

Änderung in der Größe zu nehmen als Argument eine Option ist:

public Parent (int size) 
{ 
    this.classDependentOnSize = new ClassDependentOnSize(size); 
} 

... 

public Child (String selection, String... selectionArgs) 
{ 
    super(selectionArgs.length); 
    this.DBSelection = selection; 
    this.DBSelectionArgs = selectionArgs; 
} 

Eine weitere Option , das ist ein bisschen wie ein Hack ist, ist eine init-Methode zu haben, die nach dem Bau genannt werden müssen:

abstract class Parent 
{ 
    private ClassDependentOnSize classDependentOnSize; 

    public final void init() 
    { 
     this.classDependentOnSize = new ClassDependentOnSize(size()); 
    } 

    public abstract int size(); 
} 

... 

public Child (String selection, String... selectionArgs) 
{ 
    this.DBSelection = selection; 
    this.DBSelectionArgs = selectionArgs; 
    init(); 
} 

Die rechts Antwort hier ist wahrscheinlich die Struktur Ihres Code ändern, aber ohne konkreteren det ails, kann ich keine aussagekräftige Rückmeldung geben, wie Sie das machen wollen.

+0

Ich werde meine Frage aktualisieren, um das Problem besser widerzuspiegeln. Der echte Code ist so komplex, dass ich niemanden mit nutzlosen Informationen überhäufen wollte, aber ich habe mich kurz verändert. –

+0

Leider muss das Kind die Größe berechnen. Ich kann die Größe nicht ermitteln, bevor das untergeordnete Element initialisiert wird. Dies ist ein Problem, da das übergeordnete Element zuerst initialisiert wird. –

+0

Was deine zweite Option angeht, das habe ich gemacht, aber du hattest recht, es fühlt sich wirklich wie ein Hack an, lol. –