Когда listIterator используется в качестве ссылочного типа, назначенный ему объект должен его реализовывать?

Для ссылочной переменной, тип которой является интерфейсом, объект, который вы ей назначаете, должен реализовывать интерфейс. Как это относится к интерфейсу List Iterator, которому назначается объект класса, который его не реализует (я не смог найти отношение в иерархии)

List<String> list = new ArrayList<String>();

ListIterator<Type> it = list.listIterator(list.size());---1

Я читал, что Iterator является надклассом ListIterator, но не смог найти связь между ListIterator и ArrayList или List.

Я знаю, что с интерфейсом List у него есть метод listIterator(), который помогает назначать итератор коллекциям. Но какой класс на самом деле реализует ListIterator, чтобы он был назначен ему в иерархии.

Я пытаюсь понять утверждение 1 и то, как ему присваивается это значение.


person java_enthusiast    schedule 28.08.2015    source источник
comment
Если у вас установлен JDK и вы используете Eclipse, вы можете щелкнуть ArrayList и нажать F3, чтобы увидеть исходный код ArrayList. (Затем ищите метод listIterator)   -  person user253751    schedule 28.08.2015
comment
Классы реализации не обязательно должны быть public. И они неактуальны. Метод, который возвращает фактическую реализацию, говорит вам, на какое поведение вы можете положиться.   -  person Holger    schedule 28.08.2015
comment
@immibis Я уже сделал, я знаю о существовании метода. Я просто хочу знать, что объект Arraylist должен быть назначен типу интерфейса ListIterator var, необходимо, чтобы он реализовал его или какой-то более высокий класс в иерархии для его реализации. Как это верно для этого кода?   -  person java_enthusiast    schedule 28.08.2015
comment
ArrayList не присваивается переменной ListIterator. Ему будет присвоено возвращаемое значение вызова метода listIterator(…). Это совсем другой объект.   -  person Holger    schedule 28.08.2015
comment
Классу не нужна связь с возвращаемым им объектом. Но, учитывая контракт ListIterator, это, скорее всего, внутренний класс.   -  person fabian    schedule 28.08.2015
comment
Для ссылочной переменной, тип которой является интерфейсом, объект, который вы ей назначаете, должен реализовывать интерфейс. Верно ли это для приведенного выше утверждения?   -  person java_enthusiast    schedule 28.08.2015
comment
Конечно, это правда. Но непонятно, в чем у вас проблема. Вы вызываете метод, который возвращает объект требуемого типа и присваивает его переменной этого типа. В этом нет ничего особенного. Объект списка не имеет значения.   -  person Holger    schedule 28.08.2015
comment
@Holger Я просто хочу знать, как это работает, вот и все. Где реализация интерфейса.   -  person java_enthusiast    schedule 28.08.2015


Ответы (1)


Следуя предложению комментария immibis, давайте взглянем на реализацию listIterator(int):

public ListIterator<E> listIterator(int index) {
    if (index < 0 || index > size)
        throw new IndexOutOfBoundsException("Index: "+index);
    return new ListItr(index);
}

Мы видим, что возвращаемый тип — ListIterator<E>, чего мы и ожидали (поскольку определение класса ArrayList — public class ArrayList<E>). Например, если у нас есть ArrayList<String>, тип возврата методов будет ListIterator<String>.

Но что это? Мы создаем не ListIterator, а экземпляр ListItr. Давайте посмотрим на его определение:

private class ListItr extends Itr implements ListIterator<E>

Это внутренний класс ArrayList, и он определяет некоторый класс, реализующий интерфейс ListIterator.

Итак, глядя на ваш код, мы могли бы добавить несколько скобок, чтобы было понятнее, что происходит:

ListIterator<Type> it = (list.listIterator(list.size()));

Что мы делаем, так это берем наш список, затем вызываем listIterator() в этом списке, передавая list.size() в качестве аргумента. Затем метод возвращает ListIterator, который назначается it.

ИЗМЕНИТЬ:

Я не совсем уверен, понял ли я ваш вопрос прямо перед этим. В этом случае не ArrayList должен реализовывать интерфейс ListIterator, а объект, возвращаемый методом listIterator(int), который вы вызываете для экземпляра ArrayList, поэтому это только объект, возвращаемый этим вызов метода, который должен реализовать интерфейс.

person Alex    schedule 28.08.2015
comment
Таким образом, в основном метод listIterator(int) заботится о реализации интерфейса ListIterator независимо от того, какую реализацию коллекции мы используем? - person java_enthusiast; 28.08.2015
comment
@java_энтузиаст: Каждая реализация List может иметь свою собственную реализацию listIterator(int), обеспечивая свою собственную реализацию ListIterator. Но подклассы AbstractList наследуют рабочий реализацию, которую они могут использовать или переопределить по своему усмотрению. - person Holger; 28.08.2015
comment
@java_энтузиаст Посмотрите на оператор возврата: return new ListItr(index); Итак, в основном это класс ListItr, который должен реализовать ListIterator, поскольку он возвращается из метода. И да, метод заботится о том, чтобы возвращаемый им объект — ListItr — реализовывал интерфейс (иначе код не скомпилировался бы). - person Alex; 28.08.2015