Путаница по поводу объявления объекта

Я изучаю Коллекции в книге CoreJava, и я нашел этот код:

      List<String> a = new LinkedList<String>();

Теперь мне интересно, почему этот код не такой:

LinkedList<String> a = new LinkedList<String>();

Почему мы объявляем как список?

5 ответов

Решение

Код:

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

лучше, чем:

LinkedList<String> list = new LinkedList<String>();

Это потому, что если вы объявили list как List и вы обнаружили, что производительность программы не очень хорошая, вы можете изменить код на:

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

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

В качестве вывода, если возможно, объявите ссылку в качестве интерфейса (List это интерфейс):

List<String> list;

и вы можете легко переключить реализацию (class ArrayList а также class LinkedList являются реализациями интерфейса List):

list = new LinkedList<String>();

или же

list = new ArrayList<String>();

Ваш второй будет работать и может быть предпочтительнее, если вам нужно использовать операции, специфичные для LinkedList, Но такая необходимость обычно довольно редка. Первый является более общим - он позволяет использовать другой List реализация путем изменения только одной строки. Другой код (например, параметры метода) не нужно менять.

PS Просто чтобы быть ясно - LinkedList это конкретная реализация List,

Список - это интерфейс, LinkedList - это конкретная реализация интерфейса. "Запрограммируйте на" интерфейс ", а не на" реализацию ": http://en.wikipedia.org/wiki/Design_Patterns

Еще один хороший пример.

Почему мы объявляем как список?

Рассмотрим метод:

public void doStuff(LinkedList llObj){} 

Это показывает ограничение на метод, который пользователи разрешают только передавать LinkedList.

public void doStuff(List listObj) {} 

в то время как этот метод позволяет передавать любой список.

надеюсь это поможет.

В Java, как и во всех других языках ООП, одним из основных преимуществ проектирования является полиморфизм. Полиморфизм просто не включает методы, но распространяется и на классы и принимает имена, такие как подтипы, политипизм и т. Д.

В вашем первом примере кода:

List<String> a = new LinkedList<String>();

Заставляет тип ссылочной переменной 'a' принимать любые конкретные расширения типа 'List'.

Где, как в следующем примере кода:

LinkedList<String> a = new LinkedList<String>();

Ссылочная переменная 'a' может принимать любые расширения типа 'LinkedList'.

Чтобы понять всю силу этого, мы должны проверить иерархию типов LinkedList: http://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html

Таким образом, в первом примере вы увеличиваете область ссылки "a" на любой конкретный тип "List", который также включает LinkedList, где, как и во втором примере, вы уменьшаете свою область действия до типа "LikedList" и его подтипов.

Один не лучше другого, но многое зависит от вашего дизайна кода и приложения в отношении того, какой подход лучше всего подходит для вашего варианта использования.

Некоторые хорошие чтения:

Полиморфизм подтипов: http://en.wikipedia.org/wiki/Polymorphism_(computer_science)

Другие вопросы по тегам