Вопрос

есть неизменный сорт:

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.

Это было полезно?

Решение

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

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

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

Другие советы

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

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, ?>)

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

Вам действительно нужно 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;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top