добавить (список ) где Z - интерфейс. Класс B расширяет A, реализует Z, почему мы не можем вызвать add () со списком <A> - PullRequest
0 голосов
/ 28 апреля 2020
 Interface Z{}

Рассмотрим простой интерфейс Z, как заявлено выше.

Class A{}

Простой класс A, как указано выше.

 Class B extends A implements Z{}

Класс B расширяет класс A и реализует интерфейс Z

class Test{

static void add(List<? super Z>){}

public static void main(String[]  args){
List<A> aaa= new ArrayList<>();
add(aaa);  //Gives error here
} 
}

Метод add в вышеприведенном тестовом классе имеет параметр List, насколько я знаю, я могу вызвать его с помощью alist типа Z или со списком типа суперкласс класса реализации Z.

класс B является реализацией Z, но также является потомком A, поэтому класс A удовлетворяет условию выше .Это суперкласс (класс B) класса реализации Z (класс B).

Так что когда я вызываю add () с ArrayList, почему он выдает ошибку.

1 Ответ

2 голосов
/ 28 апреля 2020

Представьте, что это тело метода add. Это прекрасно компилируется:

static void add(List<? super Z> list){
  list.add(new Z() {});  // Fine.
}

Кроме того, это хорошо компилируется.

List<A> aaa= new ArrayList<>();
// ... Something.
A a = aaa.get(0);

Теперь, что если ... Something:

add(aaa);  // Compiler error!

Что произойдет если ошибка компилятора не произошла? ClassCastException в строке A a = aaa.get(0);, потому что это экземпляр некоторого подкласса Z, который не A.

Попробуйте, вызвав add((List) aaa).

This Вот почему компилятор останавливает вас. List<? super Z> - это список, в который можно безопасно добавлять экземпляры Z или любой подкласс. List<A> - это список, в который можно безопасно добавлять экземпляры A, любого подкласса или нуля; и все, что вы извлекаете из списка, будет A, подклассом или нулем. Некоторые экземпляры Z не являются экземплярами A.

...