2016-05-15 5 views
1

Lassen Sie uns sagen, dass wir eine abstrakte Klasse, die einen Konstruktor definiert eine ganze Zahl nehmen, wo eine Voraussetzung überprüft, ob die ganze Zahl innerhalb einer Liste der möglichen Werte ist:Wie statische Element in der untergeordneten Klasse zu initialisieren?

public abstract class Value { 
    protected int value; 
    protected static List<Integer> possibleValues; 

    public Value(int val) { 
     if (!possibleValues.contains(val)) 
      throw new IllegalArgumentException("Illegal value"); 
     value = val; 
    } 
} 

Aber wir diese Liste in Value ‚s Kind initialisieren Klassen, weil jeder eine eigene Liste möglicher Werte definiert.

Ich denke, ich könnte einen static Block hinzufügen Mitglieder possibleValues, obwohl ich nicht static Blöcke. Das bedeutet jedoch nicht, dass alle untergeordneten Klassen nicht mehr auf die gleiche Liste möglicher Werte zeigen würden.

Wie kann ich erzwingen, dass die untergeordneten Klassen eine Liste möglicher Werte definieren und die Vorbedingungsprüfung durchführen, ohne die beschriebenen Probleme zu behandeln?

Edit: also könnten wir sagen, ich möchte das Verhalten erben, aber nicht die Variable selbst.

+0

Warum nicht eine abstrakte 'isValid' Methode definieren, die Kind-Klassen ausfüllen? Oder lassen Sie Value mit einer ValueChecker-Klasse templatisieren, die von abgeleiteten Klassen bereitgestellt wird? – Robert

+0

Ich würde vorschlagen, ein Set anstelle einer Liste zu verwenden. Außerdem wäre die Verwendung eines Fabrikmusters brauchbarer und sauberer. –

Antwort

2

Wie wäre:

public abstract class Value { 
    protected int value; 
    protected abstract List<Integer> getPossibleValues(); 

    public Value(int val) { 
     if (!getPossibleValues().contains(val)) 
      throw new IllegalArgumentException("Illegal value"); 
     value = val; 
    } 
} 

wird Ihre Unterklassen zu implementieren getPossibleValues() gezwungen werden.

+2

Die allgemeine Idee ist nett, aber hier haben Sie einen Konstruktor Aufruf einer Unterklasse überschreiben Methode, die eine schlechte Idee ist: http://StackOverflow.com/Questions/3404301/whats-wrong-with-overridable-method-calls-in- Erbauer –

+0

@dabadaba: es war nur eine Idee von der Spitze meines Kopfes. Oliver hat darauf hingewiesen, dass es nicht die beste Idee ist und ein besseres Design gefunden werden kann. – Burkhard

+0

@Oliver Es wird so weit gehen, weil die Elternklasse nicht vererbt wird. Ich habe die absolute Kontrolle darüber. Aber welche Alternative würden Sie aus Neugier vorschlagen? – dabadaba

0

Wie wäre es so etwas wie:

public abstract class Value { 
    int value; 

    protected Value(int val, List<Integer> possibleValues) { 
     if (!possibleValues.contains(val)) { 
      throw IllegalArgumentException(); 
     } 
     this.value = val; 
    } 
} 

class SubValue extends Value { 
    private static final List<Integer> possibleValues = ...; 
    SubValue(int val) { 
     super(val, possibleValues); 
    } 
} 
+0

Warum sollten sie sich daran erinnern, das zu tun? Der springende Punkt meines Entwurfs war, das Verhalten (Vorbedingungsprüfung) in die Elternklasse aufzunehmen, so dass die Kindklassen das nicht tun müssten. – dabadaba

+0

@dabadaba stimmte zu. Habe gerade die Antwort mit etwas aktualisiert, was ich für eine bessere Option halte. –

Verwandte Themen