Подтвердить что ты не робот

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

У меня есть класс 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?

Спасибо!

4b9b3361

Ответ 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 хочет его избежать - поэтому нет ковариации параметров.