Общий возврат - PullRequest
       50

Общий возврат

1 голос
/ 11 мая 2009

существует неизменный класс:

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

имеет много аналогичные методы расширены на:

Timerange extends Scope<Date>

и многие другие (также неизменные).

Мне бы хотелось, чтобы они возвращали объект своего типа. Например:

timerange.crop(scope)

должен возвращать объект Timerange, а не Scope.

Должен ли я переопределять каждый метод (или использовать отражение)? Есть ли другой способ сделать это?

Заранее спасибо, Etam.

Ответы [ 4 ]

4 голосов
/ 11 мая 2009

Вам нужна какая-то фабрика. В этом случае заводской метод работает нормально.

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 (...);
    }
}

Возможно, вы захотите добавить общий параметр this в базовый класс:

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 (...);
    }
}

Это добавляет дополнительную работу к клиентскому коду.

2 голосов
/ 11 мая 2009

Вы можете попробовать следующее:

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

TimeRange будет определен как

class TimeRange extends Scope<Date, Timerange>

и поэтому crop вернет объект TimeRange. Когда производный класс не определен, вы можете использовать универсальные шаблоны (Scope<Date, ?>)

2 голосов
/ 11 мая 2009

Java не имеет возвращаемых значений, поэтому вам обычно нужно вручную переопределять каждый метод. См. мой блог о "типах" для обсуждения некоторых возможных альтернатив.

0 голосов
/ 11 мая 2009

Вам действительно нужно Timerange? Он предлагает что-то большее, чем просто Scope<Date>? Если нет, то просто используйте Scope<Date>.

Другое предложение состоит в том, что, возможно, вместо того, чтобы создавать его с помощью конструктора, вы можете клонировать объект, а затем изменить поля соответствующим образом для нового объекта. Причина в том, что клонированный объект того же типа, что и оригинал.

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...