Как я могу переопределить метод, возвращающий List, содержащий экземпляры подкласса, в класс, содержащийся в оригинальных методах List? - PullRequest
2 голосов
/ 14 февраля 2020

Я понимаю, что название немного грязное, но это лучшее, что я могу придумать.

Ниже приведен минимальный пример того, что я буду sh, но в настоящее время я не могу это сделать.

public class ObjectA {}

public class ObjectB extends ObjectA {}

public interface HandlerInterface<T extends ObjectA> {

        public T easyToOverride();

        public List<T> hardToOverride();

}      

public class HandlerA implements HandlerInterface<ObjectA> {

        public ObjectA easyToOverride() {
                return new ObjectA();
        }

        public List<ObjectA> hardToOverride() {
                return new ArrayList<ObjectA>();
        }
}      

public class HandlerB extends HandlerA implements HandlerInterface<ObjectB> {

        /*
          This method ovverides its super method with ease since its return
          type directly inherits from the super class's return type
        */
        public ObjectB easyToOverride() {
                return new ObjectB();
        }

        /*
          This method is NOT accepted by the Java syntax since List<ObjectB>
          does NOT directly inherit from List<ObjectA>

          The method signature for hardToOverride() clashes with the signature
          in the super class and is not overridden because the return types
          don't obviously inherit each other
        */
         public List<ObjectB> hardToOverride() {
                return new ArrayList<ObjectB>();
        }
} 

Игнорируйте, что эти классы должны быть в их собственных файлах и что я не включил их импорт. Я просто сформулировал это так, чтобы было легче читать.

Как вы, возможно, поняли из комментариев в классе HandlerB, метод hardToOverride() не принят (бросьте этот код в вашу IDE и смотреть, как это кричать).

Я понимаю, что мог бы просто вернуть List<Object> и набрать приведение содержимого возвращенного объекта List к типу, который, как мне лично известно, возвращает указанный экземпляр обработчика c (ObjectA или ObjectB), но это будет означать, что любой, кто использует эти методы, должен понимать их внутреннюю работу, и мне это не нравится.

Я хочу иметь возможность переопределить List<ObjectA> hardToOverride() метод с методом List<ObjectB> hardToOverride() без потери жесткой типизации, которую обеспечивают эти методы.

Итак, мой последний вопрос:

Есть ли способ сохранить все эти интерфейсы, наследования и переопределяет, не теряя строгой типизации, которую они предоставляют в моем примере кода?

Если нет, то как лучше получить подобный набор классов и интерфейсов, который действительно работает? * 102 6 *

1 Ответ

1 голос
/ 14 февраля 2020

Ваш код будет принят, если вы объявите HandlerA с новым универсальным c, даже если он никогда не использовался:

public class HandlerA<T> implements HandlerInterface<ObjectA> {
//....
}

ПРИМЕЧАНИЕ: Это должно быть рассматривается как обходной путь, но в результате ваш пример кода будет работать так, как вы просили. Более того, даже если HandlerA объявляет универсальный c, вы можете в любом случае создать его экземпляр также без скобок:

ObjectA objectA = new HandlerA();
...