Когда мы пишем такой код:
List<String> myList = new ArrayList<>();
мы создаем объект типа ArrayList
, но не объект типа List
. Дело в том, что List
является интерфейсом, а не конкретным классом, поэтому его нельзя напрямую инстанцировать. Интерфейсы в Java представляют собой набор методов без их реализации, а классы, реализующие эти интерфейсы (например, ArrayList
или LinkedList
), предоставляют конкретную реализацию этих методов.
Почему интерфейс нельзя инстанцировать?
“Инстанцировать” (от англ. instantiate) означает создать экземпляр (объект) класса в программировании. Когда мы говорим, что мы “инстанцируем класс”, это значит, что мы используем класс как “шаблон” для создания конкретного объекта в памяти, которому можно присвоить свойства и методы, описанные в этом классе.
Интерфейс — это контракт, который определяет, какие методы должен реализовать класс, но не указывает, как именно они должны быть реализованы. Это объясняет, почему мы не можем создать экземпляр интерфейса напрямую: он не содержит кода для выполнения своих методов.
Почему используется List<String>
, а не ArrayList<String>
?
Использование типа List<String>
для переменной myList
обеспечивает гибкость кода. Мы можем заменить реализацию, например, на LinkedList
, Vector
, или другую реализацию List
без изменения кода в других местах, которые работают с myList
.
Таким образом, при написании List<String> myList = new ArrayList<>();
мы говорим компилятору:
- “Используй интерфейс
List
для определения того, какие методы доступны дляmyList
.” - “Создай конкретный объект типа
ArrayList
, который реализует интерфейсList
.”