Frage

gibt es eine unveränderlich Klasse:

Scope<Cmp extends Comparable<Cmp>>
public Scope<Cmp> crop(Scope<Cmp> scope) {
    ...
    return new Scope<Cmp>(starts, ends);
}

hat viele ähnliche Verfahren wird erweitert durch:

Timerange extends Scope<Date>

und viele andere (auch unveränderlich).

Id wie sie Gegenstand seiner Art zurückzukehren. Zum Beispiel:

timerange.crop(scope)

sollte Timerange zurückzukehren Objekt, nicht Scope.

Muss ich jede Methode (oder Verwendung Reflexion) außer Kraft setzen? Gibt es eine andere Art und Weise, dies zu tun?

Vielen Dank im Voraus, Etam.

War es hilfreich?

Lösung

Sie brauchen eine Art Fabrik. In diesem Fall Factory-Methode funktioniert.

public abstract class Scope<E extends Comparable<E>> {
    abstract Scope<E> create(E start, E end);

    public Scope<E> crop(Scope<E> scope) {
        ...
        return create(starts, ends);
    }
}
public TimeRange extends Scope<Date> {
    Scope<Date> create(Date start, Date end) {
        return new TimeRange (...);
    }
}

Sie können einen generischen ‚diesen‘ Parameter auf die Basisklasse hinzuzufügen:

public abstract class Scope<THIS extends Scope<THIS, E>, E extend Comparable<E>> {
    abstract THIS create(E start, E end);

    public THIS crop(Scope<E> scope) {
        ...
        return create(starts, ends);
    }
}
public TimeRange extends Scope<TimeRange,Date> {
    TimeRange create(Date start, Date end) {
        return new TimeRange (...);
    }
}

Dies fügt zusätzliche Arbeit an den Client-Code.

Andere Tipps

Sie könnten versuchen, die folgende:

class Scope<Cpm extends Comparable<Cpm>, Derived extends Scope<Cpm, Derived>> {
  public Derived crop(Scope<Cmp, Derived> scope)
}

Timerange würde als

definiert werden
class TimeRange extends Scope<Date, Timerange>

und so würde crop ein Timerange-Objekt zurück. Wenn die Ableitungs Klasse nicht definiert ist, können Sie generische Platzhalter verwenden (Scope<Date, ?>)

Java hat nicht selbstTyp zurückgibt, so müssen Sie in der Regel manuell jede Methode außer Kraft setzen. Siehe mein Blog auf "self-Typen" für ein Diskussion mit einigen möglichen Alternativen.

Haben Sie wirklich brauchen Timerange? Bietet es etwas mehr als nur Scope<Date>? Wenn nicht, dann nur Scope<Date> verwenden.

Ein weiterer Vorschlag ist, dass vielleicht, anstatt es zu instanziieren den Konstruktor verwenden, können Sie das Objekt klonen, und ändern Sie dann die Felder in geeigneter Weise für das neue Objekt. Der Grund dafür ist, dass das geklonte Objekt ist vom gleichen Typ wie das Original.

Scope<Cmp extends Comparable<Cmp>> implements Cloneable
public Scope<Cmp> crop(Scope<Cmp> scope) {
    ...
    Scope<Cmp> result = (Scope<Cmp>)super.clone();
    result.init(starts, ends); // sets the fields for a cloned object
                               // init() could be private
    return result;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top