Не проще ли работать с foo, когда он представлен классом ArrayList, а не интерфейсом List? - PullRequest
3 голосов
/ 23 августа 2010

Я часто вижу этот синтаксис и не понимаю причин, стоящих за ним. Я думал, что вы, как правило, хотите работать с классами, а не с интерфейсами, чтобы упростить выполнение всего набора операций, которые вы, возможно, захотите выполнить.

Зачем это делать:

List<Foo> foo = new ArrayList<Foo>(something.getFoo());

вместо этого:

ArrayList<Foo> foo = new ArrayList<Foo>(something.getFoo());

когда вы позже захотите выполнить операции с foo? Не проще ли, если foo представлен классом ArrayList, а не интерфейсом List?

Ответы [ 3 ]

11 голосов
/ 23 августа 2010

Иногда да.Если вы на самом деле нуждаетесь в методе, который объявлен в ArrayList<T>, но не в List<T>, тогда, конечно, продолжайте.

Однако обратное более гибко - если вы не нужны какие-либо методы, объявленные в ArrayList<T>, тогда ваш код может выразить это, объявив вместо этого переменную типа List<T>.Это говорит: «Мне просто нужен список. Я случайно выбираю ArrayList<T>, но только потому, что его поведение меня устраивает ... не потому, что мне нужны какие-либо дополнительные функции, которые он предоставляет».

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

Например,если я вижу переменную типа Iterable<T>, я знаю, что с ней мало что можно сделать позже: в основном она будет использоваться для итерации, и все.Мне не нужно беспокоиться о том, попытается ли какой-либо более поздний код добавить значение в коллекцию или получить к нему доступ по индексу и т. Д.

Это относительно неважно для локальных переменных, но в большей степени это касается переменных экземпляра и, в частности, параметров: чем менее конкретны вы задаете параметры, тем больше гибкости у вызывающей стороны в отношении того, какие аргументы они передадут.

1 голос
/ 23 августа 2010

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

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

Если много используется конкретных реализаций, вы получите искаженный код, когда получите LinkedList из метода A и ArrayList из метода B.

Программирование на основе интерфейсов также упрощает моделирование объектов при модульном тестировании.

0 голосов
/ 23 августа 2010

Смысл полиморфизма в том, чтобы НЕ связывать вашу реализацию с реализацией другого типа данных.В этом случае вы не хотите женить свой класс на ArrayList.Скорее, вы хотите женить свой класс на абстрактном типе List.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...