Возврат конкретного объекта в универсальный метод с универсальным параметром Map во время переопределения - PullRequest
0 голосов
/ 23 октября 2018

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

public interface GarrageSimple {
    <T extends Car> T getCar(Map<String, T> c);
}

Ниже приведена реализация, которая выдает ошибку: Несовместимые типы.Требуется: T Найдено: Bmw

public class GarrageSimpleImpl implements GarrageSimple {

    @Override
    public <T extends Car> T getCar(Map<String, T> c) {
        return new Bmw();
    }
}

На самом деле, Bmw является подклассом Car, что означает тип T. Когда я разыгрываю его как* return (T) new Bmw (); * работает с предупреждением, что Не проверено приведение Bmw к T

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

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

Спасибо

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Вы не можете.Универсальный метод (метод, который объявляет свои собственные параметры типа) означает, что ваш метод должен работать независимо от того, какие параметры типа (здесь T).Метод не может выбрать, что T использовать.Вызывающий может вызвать ваш метод с T, который находится в пределах T, и ваш метод должен корректно работать с тем, что T не имеет выбора.

Подкласс, переопределяющий метод в суперклассе, означаетчто метод подкласса должен быть допустимой заменой переопределенного метода, что означает, что он должен работать во всех ситуациях, в которых может быть вызван переопределенный метод. Поскольку переопределенный метод является универсальным и работает для любого T, ваш метод подклассакоторый переопределяет, он также должен работать для любого T.Ваш метод не работает для любого T - он не работает для любого T, который не Bmw.

0 голосов
/ 23 октября 2018

Нет, это недействительно.Что произойдет, если кто-то со ссылкой GarrageSimpleImpl назвал его с другим классом, расширяющим Car?Дженерики все о безопасности времени компиляции, и именно поэтому вы получаете эту ошибку.

Но вы можете сделать это так,

public interface GarrageSimple<T extends Car> {
     T getCar(Map<String, T> c);
}


public class GarrageSimpleImpl implements GarrageSimple<Bmw> {
    @Override
    public Bmw getCar(Map<String, Bmw> c) {
        return new Bmw();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...