Поменяйте местами двух детей в методе, определенном ArrayList <? расширяет Parent>

1

Мой вопрос основан на ответе на предыдущий вопрос:

Почему мы не можем сделать List <Parent> mylist = ArrayList <child>();

У меня есть функция, которая сортирует список дочерних элементов, который передается ему на основе параметров родительской функции. Поскольку существует много разных типов детей, я написал функцию, которая получает родительский родительский тип.

void sort(ArrayList<? extends Parent> passedList)

Позже в функции я хотел бы обменять два члена (i и j) ArrayList, но я не могу понять, как это сделать. Я пытался:

Parent swap;
swap = passedList.get(i);
passedList.set(i,passedList.get(j));
passedList.set(j,swap);

Однако это не будет компилироваться, и он говорит, что типы не совместимы в заданной функции. Тип, который я получаю от get, является Parent, но set ожидает тип (? Extends Parent). Я также попытался объявить своп как ? extends Parent swap; ? extends Parent swap; или путем литья, как в

passedList.set(i,(? extends Parent)passedList.get(j));

Похоже, должно быть возможно видеть, как мы можем гарантировать, что объект, возвращенный параметром passList.get(), является правильным типом, который должен принадлежать в arraylist.

Теги:
arraylist
polymorphism
inheritance

2 ответа

1
Лучший ответ

Похоже, должно быть возможно видеть, как мы можем гарантировать, что объект, возвращенный параметром passList.get(), является правильным типом, который должен принадлежать в arraylist.

Мы можем сказать, что это правильно, потому что мы можем смотреть на код и отслеживать обратно туда, откуда приходит swap. Но компилятор не может сказать, потому что язык не гарантирован. Вы пытаетесь поставить Parent в List<? extends Parent> List<? extends Parent>, а в списке может быть некоторый подтип, например List<Child>.

Вместо этого вы можете выполнить это с помощью подстановочных знаков:

static <P extends Parent> void swap(List<P> list, int i, int j) {
    P temp = list.get(i);
    list.set(i, list.get(j));
    list.set(j, temp);
}

Это позволяет вам выразить, что тип temp такой же, как и фактический аргумент типа для list.

Смотрите также:

1

<? extends Parent> <? extends Parent> обещает, что список представляет собой список, содержащий Parents, или список, содержащий подкласс Parent, например ArrayList<Child>.

Это означает, что вы всегда можете получить объект в качестве Parent, но вы не можете вернуть Parent туда, поскольку фактический тип списка может быть не Parent (и вы не можете поместить Parent в List<Child>).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню