Хорошо, во-первых, ваша иерархия классов нарушена - это не будет компилироваться. Помните, что базовый класс становится «частью» вашего производного класса. Это означает: а) у вас есть три разных 'i' (по одному в каждом классе) б) вы не инициализируете i
в своем суперклассе, потому что у вас нет конструктора по умолчанию (без аргументов), и у вас нет позвоните super (i). Давайте исправим это:
class X {
int i;
X(int i) { this.i = i; }
}
class Y extends X {
Y(int i) { super(i); }
}
class Z extends Y {
Z(int i) { super(i); }
}
Теперь к собственному вопросу: всегда помните PECS - Producer extends, Consumer super Это означает, что если у вас есть, например, коллекция, которую вы хотите запросить, т.е. для получения результатов из в типобезопасном вопросе вам необходимо использовать границы с extends . Если вы хотите использовать значения, например, поместить что-то в коллекцию, используйте super.
Почему? Таким образом, «super» и «extends» - это верхний и нижний пределы:
Для «потребления» <? extends Y>
означает «Я буду принимать только классы, которые расширяет Y, а <? super Y>
означает:« Я буду принимать только классы, где Y » является суперклассом ".
В вашем случае вы пишете метод, который должен принимать Queue<Y>
или Queue<Z>
- поэтому вы говорите:« Мои методы должны принимать очереди типов, где Y - супер введите "
Это будет работать:
public class Wildcards {
static void rtn(Queue<? super Y> q) {
q.add(new Y(5));
q.add(new Z(5));
}
public static void main(String[] args) {
Queue<Y> q = new LinkedList<>();
rtn(q);
}
}
См. https://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html