2015-06-26 3 views
-1

Я использую метод, который возвращает тип List<>, и я тогда в состоянии вызвать методы на этом List:Почему объявление не требуется?

List<Artist> artists = artistsPager.artists.items; 
artists.add(new Artist()); 

Чтобы быть ясно artistsPager.artists.items является тип List<Artist> возвращения.

Поскольку List только интерфейс, как компилятор позволил мне использовать этот artists объект, никак не List<> всегда нуждается в реализации, как ArrayList?

Например, компилятор не позволит мне сделать следующее, потому что «Список является абстрактным, не может быть реализован»:

List<Integer> list = new List<Integer>(); 

Как artistsPager.artists.items чем отличается new List<Integer>()?

Для любопытных, это исходит от Java Web API wrapper for Android. Вся помощь очень ценится.

Я не верю, что это дубликат этого question, потому что, хотя ответы одинаковы, вопрос, который их порождает, различен. Другой вопрос задает разницу между типами List и ArrayList, тогда как мой вопрос задавался вопросом, почему компилятор не жаловался, когда была скрыта реализация List.

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

+1

Вы должны найти интерфейсы/абстрактные классы и посмотреть, как они используются на Java. Это важный набор знаний, особенно при работе с такими высококлассными библиотеками, как Android и JDK, поскольку интерфейсы используются почти везде в них. –

+0

Спасибо @DaveLugg, я был в замешательстве, потому что я просмотрел исходный код Spotify API и не смог найти никакого его создания как ничего, кроме типа List. В следующий раз я буду доверять компилятору! Есть ли какой-нибудь быстрый способ выяснить, где фактически реализован List <>, а не перемещаться по коду? – Richard

+1

Точка использования интерфейсов заключается в том, что вам не важно, где это реализовано, просто это «Список». Тип ArrayList является его реализацией и, вероятно, является наиболее распространенным. Таким образом, вы можете использовать 'List list = new ArrayList ();'. Вы можете найти реализации по умолчанию интерфейса List в документах oracle (https://docs.oracle.com/javase/6/docs/api/java/util/List.html) и посмотреть «Все известные классы реализации» –

ответ

3

Как художникиПарт.artists.items отличается от new List<Integer>()?

artistsPager.artists.items является полем типа List<>. Где-то в коде он должен быть создан с конкретной реализацией, например, ArrayList.

new List<Integer>() - это вызов конструктора, который недействителен, поскольку List - это интерфейс.

+0

Получил это, я думаю, я был в замешательстве, потому что не видел конкретной реализации типа List <>. – Richard

0

Это означает, что где-то был создан конкретный список (например, ArrayList).

Вы только знаете, что созданный список реализует методы из интерфейса List, позволяя использовать эти методы.

Возьмите этот пример скрывается бетон LinkedList от пользователя:

public static List<Integer> makeListOfInts(){ 
    return new LinkedList<Integer>(){ 
     { 
      add(1); 
      add(2); 
     } 
    } 
} 

I может быть легко заменен ArrayList:

public static List<Integer> makeListOfInts(){ 
    return new ArrayList<Integer>(){ 
     { 
      add(1); 
      add(2); 
     } 
    } 
} 

И все пользовательские работы функции знает, что List возвращается , но он не знает конкретного типа списка. Он может использовать только функции из интерфейса List, а не от конкретной реализации, которая была выбрана.

2

не List<> всегда нужна реализация, например ArrayList<>?

Да, для создания экземпляра необходима реализация. Однако компилятор знает две вещи:

  • Он знает, что вы уже создали некоторые экземпляр, и назначили его items и
  • Он знает, что все, что вы назначили на items, реализует List<> интерфейс

Зная эти две вещи, достаточно, чтобы компилятор разрешил вам звонить add на переменную, объявленную как тип интерфейса. Таким образом, ваш код не должен заботиться о том, какую реализацию вы получаете - ArrayList<>, a LinkedList<> или какую-то специальную реализацию, которую вы разработали: ваш код будет работать со всеми из них.

Обратите внимание, что практика обращения к объектам через их тип интерфейса является желательной. Он называется программирования для интерфейса. Это позволяет вам скрывать детали реализации и затем обменивать объекты для разных реализаций.

Смежные вопросы