Когда мы пишем такой код:
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.”
