Есть ли лучшее решение для абстрактного класса A <T extends A>? - PullRequest
2 голосов
/ 06 апреля 2011

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

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

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

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

}

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

1 Ответ

1 голос
/ 06 апреля 2011

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

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
    }
}
...