Передача производного класса методу, который необходимо переопределить, ожидая базовый класс
У меня есть класс A с абстрактным методом doAction (BaseClass obj), ожидающим параметр типа BaseClass
public class A {
//....
abstract void doAction(BaseClass obj);
//....
}
Теперь у меня есть еще один класс B, который должен расширять A. Однако B метод doAction должен использовать объект DerivedClass, который расширяет BaseClass.
public class B extends class A {
//..
void doAction(DerivedClass obj) {
obj.callMethodAvailableOnlyInDerivedClass();
}
}
Как мне обрабатывать эту ситуацию, когда мне нужно передать параметр типа DerivedClass методу, который нужно переопределить, когда он ожидает BaseClass?
Спасибо!
Ответы
Ответ 1
Вы делаете базовый класс общим:
public class A<T extends BaseClass> {
//....
abstract void doAction(T obj);
//....
}
и подкласс, параметризованный производным классом:
public class B extends A<DerivedClass> {
//..
void doAction(DerivedClass obj) {
obj.callMethodAvailableOnlyInDerivedClass();
}
}
Без генераторов это невозможно, потому что B нарушит контракт A: A принимает любой тип BaseClass, но вы извлекаете B, чтобы принимать только определенный подкласс. Это не соответствует принципу Лискова.
Ответ 2
Вы можете использовать:
public abstract class A<T extends BaseClass> {
//....
abstract void doAction(T obj);
//....
}
public class B extends class A<DerivedClass> {
//..
void doAction(DerivedClass obj) {
obj.callMethodAvailableOnlyInDerivedClass();
}
}
Ответ 3
В java нет параметров Contra-Variance, поскольку это не безопасно.
Предположим, что у вас есть A a = new B();
И затем вы вызываете a.doAction(new BaseClass())
Что произойдет?
Это вызовет ошибку времени выполнения, так как B
не знает "что" с BaseClass
. java хочет его избежать - поэтому нет ковариации параметров.