Я изучаю коллекции в книге CoreJava и нашел этот код:
List<String> a = new LinkedList<String>();
Теперь мне интересно, почему этот код не такой:
LinkedList<String> a = new LinkedList<String>();
Почему мы объявляем a как список?
Я изучаю коллекции в книге CoreJava и нашел этот код:
List<String> a = new LinkedList<String>();
Теперь мне интересно, почему этот код не такой:
LinkedList<String> a = new LinkedList<String>();
Почему мы объявляем a как список?
Код:
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>();
or
list = new ArrayList<String>();
Список — это интерфейс, LinkedList — это конкретная реализация интерфейса. «Программируйте «интерфейс», а не «реализацию»: https://en.wikipedia.org/wiki/Design_Patterns#Introduction.2C_Chapter_1
Ваш второй будет работать и может быть предпочтительнее, если вам нужно использовать операции, специфичные для LinkedList
. Но такая потребность обычно возникает довольно редко. Первый более общий — он позволяет вам использовать другую реализацию List
, изменив всего одну строку. Другой код (например, параметры метода) менять не нужно.
P.S. Просто для ясности: LinkedList
— это конкретная реализация List
.
еще один хороший пример.
Почему мы объявляем список как список?
Рассмотрим метод:
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: https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html
Таким образом, в первом примере вы увеличиваете объем ссылки «a» на любой конкретный тип «Списка», который также включает LinkedList, где, как и во втором примере, вы уменьшаете область действия только до типа «LikedList» и его подтипов.
Один не лучше другого, но многое зависит от вашего дизайна кода и приложения, в зависимости от того, какой подход лучше всего подходит для вашего варианта использования.
Некоторые хорошие чтения:
Полиморфизм подтипов: https://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping