Почему void say(List< ? extends Number> list)
не может быть заменен на void say(List< Number> list)
.Превалирующий метод обобщения 8
Имя столкновения возникает, когда вы пытаетесь скомпилировать.
Почему void say(List< ? extends Number> list)
не может быть заменен на void say(List< Number> list)
.Превалирующий метод обобщения 8
Имя столкновения возникает, когда вы пытаетесь скомпилировать.
Вы не можете переопределить метод объявлен как
void say(List<? extends Number> list) // A
с
void say(List<Number> list) // B
просто потому, что типы не эквивалентны. Например, List<Integer>
соответствует List<? extends Number>
но не List<Number>
, так
List<Integer> integers = Arrays.<Integer>asList(1, 2, 3);
a.say(integers); // is valid assuming signature A
b.say(integers); // does not compile
(см этот вопрос для получения подробной информации о generics, wildcards, and type relationships). Если компилятор сделал позволит вам переопределить так, как вы хотите, то следующий будет возможно:
class A {
void say(List<? extends Number> numbers) { }
}
class B extends A {
void say(List<Number> numbers) { numbers.add(Double.valueOf(1.0)); }
}
List<Integer> onlyIntsPlease = new ArrayList<Integer>();
B b = new B();
// Oops! The list of `Integer` will now contain a `Double`...
b.say(onlyIntsPlease);
Это невозможно как на общих теоретических основаниях и в связи со спецификой Java дженериков.
Общий принцип заключается в том, что основной метод должен быть заменяемым для метода базового класса. Например, метод подкласса может использовать расширенный модификатор доступа, но не более узкий. В вашем случае,
void say(List<Number> list)
более ограничительный, чем
void say(List<? extends Number> list)
так что это явно нарушает принцип заменимости.
Практического препятствие заключается в следующем: наиважнейший о выполнение полиморфизма, в то время как Дженерик о время компиляции полиморфизма и параметры типа экземпляра не доступны даже к механизму способа доставки.
В каком языке программирования? – tbsalling