Есть ли лучшее решение для абстрактного класса A‹T extends A›?

Я хочу переопределить метод и заменить параметр, который он принимает, подклассом этого параметра.

Для возвращаемого типа проблем нет, потому что они не являются частью сигнатуры метода и могут быть заменены подклассами (так называемые "ковариантные возвращаемые типы"). Для аргументов это не работает, потому что они являются частью подписи.

Итак, я нашел решение использовать общий параметр того же типа:

public abstract class A<T extends A> {

  public void loadValuesFrom(T source) {
    ...
  }

}

public class B extends A<B> {

  public void loadValuesFrom(B source) {
    super.loadValuesFrom(source);
    ...    
  }

}

Но утверждение «общедоступный абстрактный класс A» кажется мне странным. Есть ли другие способы добиться этого? Любой «ковариантный тип параметра»? :-)


person Andrej    schedule 06.04.2011    source источник


Ответы (1)


Если это должен быть тип параметра, использование дженериков, вероятно, является лучшим вариантом. Я бы сделал только небольшую поправку, чтобы избежать необработанного типа в объявлении класса:

public abstract class A<T extends A<T>> {

Однако, если у вас есть особый случай, когда инициализируемый объект должен быть заново создан, вы можете включить создание в метод, тем самым устраняя необходимость передавать этот объект в качестве параметра:

public abstract class A {
    public A clone() {

    }
}

public class B extends A {
    public B clone() {
        // copy state
    }
}
person meriton    schedule 06.04.2011