Подтвердить что ты не робот

Причина для - Список list = new ArrayList();

Я видел такой код много раз:

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

Почему люди берут родительский элемент ArrayList (и других классов) вместо типа сгенерированного объекта?

Это снижает производительность? Или зачем кому-то это делать?

4b9b3361

Ответ 1

Когда кто-то пишет такой код, он/она пытается следовать основному принципу дизайна OO, который говорит -

Программа для интерфейса, а не для конкретной реализации

Я объяснил этот принцип в одном из моих сообщений в блоге. Посмотрите раздел Class Inheritance VS Interface Inheritance.

Чтобы суммировать сообщение, когда вы используете ссылку родительского типа для ссылки на экземпляр подтипа, вы получаете большую гибкость. Например, если вам когда-либо понадобится изменить реализацию подтипа в будущем, вы сможете сделать это легко, не изменяя большую часть своего кода.

Рассмотрим следующий метод -

public void DoSomeStuff(Super s) {
    s.someMethod();
}

и вызов этого метода -

DoSomeStuff(new Sub());

теперь, если вам когда-либо понадобится изменить логику внутри someMethod, вы можете легко сделать это, объявив новый подтип Super, скажем NewSubType, и изменив логику внутри этой реализации. Таким образом, вам никогда не придется касаться другого существующего кода, который использует этот метод. Вы все равно сможете использовать свой метод DoSomeStuff следующим образом:

DoSomeStuff(new NewSubType());

Если бы вы объявили параметр DoSomeStuff равным Sub, вам также пришлось бы изменить его реализацию -

DoSomeStuff(NewSubType s) {
    s.someMethod();
}

и он может также цепью/пузырьком в нескольких других местах.

Что касается примера вашей коллекции, это позволяет вам изменить реализацию списка, на которую указывает переменная, без особых хлопот. Вы можете легко использовать LinkedList вместо ArrayList.

Ответ 2

Это означает, что вы можете поменять тип list в любой точке на все, что реализует интерфейс list, в отличие от создания жесткой модели, которая может использовать только ArrayList. Например:

private List<String> list;

public SomeConstructor()
{
     // At this point, you can make it any type of object you want.
     list = new ArrayList<String>();
     list = new LinkedList<String>();
     list = new AttributeList<String>();
}

Это будет abstract ваш код, который использует объект list, вдалеке от деталей, таких как точный тип объекта list. Все, что ему нужно знать, это то, что у него есть метод add и т.д. Это называется Loose Coupling.

Ответ 3

Когда вы пишете:

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

Тогда вы уверены, что будете использовать только функциональные возможности интерфейса List.
(ArrayList реализует List, поэтому List больше flexibl). Используя это, вы можете изменить ArrayList на другие типы в будущем (например, LinkedList..).

Ответ 4

Чтобы разобраться:

Для большей гибкости вы инициируете интерфейс List:

Итак, если вам не нужно все ArrayList использовать только List.

Вы можете написать что-то вроде: List<String> = Arrays.asList("aa", "bb","cc").

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

enter image description here

Взял из здесь

Ответ 5

Поскольку метод не должен знать, какую версию-реализацию вы используете.

Метод просто должен знать, что есть список.

Метод все еще можно использовать.

Всегда программируйте интерфейс, а не конкретную реализацию. (В этом случае List)

Ответ 6

В общем случае предпочтительнее работать с классом Interface (List в этом случае), так что любая реализация списка впоследствии может быть заменена минимальной проблемой при изменении требований.

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

Ответ 7

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

В рамках коллекции List есть интерфейс, а ArrayList - реализация. Основная причина, по которой вы это сделаете, состоит в том, чтобы отделить ваш код от определенного implementation интерфейса, и это будет полезно в случае, если вы захотите перейти к другой реализации List в будущем.