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

Почему переменные объявлены с их именем интерфейса в Java?

Это реальный вопрос для начинающих (я все еще изучаю основы Java).

Я могу (вроде) понять, почему методы возвращают List <String> а не ArrayList <String> , или почему они принимают параметр List, а не ArrayList. Если это не имеет никакого значения для метода (то есть, если не требуются специальные методы из ArrayList), это сделает метод более гибким и более простым в использовании для вызывающих. То же самое относится к другим типам коллекций, например Set или Map.

Что я не понимаю: для создания таких локальных переменных, как правило, существует обычная практика:

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

Хотя эта форма встречается реже:

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

Какое преимущество здесь?

Все, что я вижу, является незначительным недостатком: отдельная строка импорта для java.util.List должна быть добавлена. Технически "import java.util. *" Можно было бы использовать, но я не вижу этого очень часто, вероятно, потому, что строки "импорта" автоматически добавляются некоторыми IDE.

4b9b3361

Ответ 1

Когда вы читаете

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

вы понимаете, что все, что вам нужно, это List<String>, и вы уделяете меньше внимания фактической реализации. Кроме того, вы ограничиваетесь членами, объявленными List<String>, а не конкретной реализацией. Вас не волнует, хранятся ли ваши данные в линейном массиве или какой-либо причудливой структуре данных, если она похожа на List<String>.

С другой стороны, чтение второй строки дает вам представление о том, что код заботится о переменной ArrayList<String>. Написав это, вы неявно говорите (будущим читателям), что вы не должны слепо изменять тип фактического объекта, потому что остальная часть кода полагается на то, что это действительно ArrayList<String>.

Ответ 2

Использование интерфейса позволяет быстро изменить базовую реализацию List/Map/Set/etc.

Это не о сохранении нажатий клавиш, а об изменении быстродействия. В идеале вы не должны раскрывать базовые конкретные методы реализации и просто использовать требуемый интерфейс.

Ответ 3

Я бы предложил подумать об этом с другого конца. Обычно вам нужен список или набор или любой другой тип коллекции, и вам действительно не нравится, как именно это реализовано. Следовательно, ваш код просто работает со списком и выполняет все, что ему нужно (также обозначается как "всегда код для интерфейсов" ).

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

Например, у меня есть привычка иметь отладочный код в моем основном методе, который сбрасывает системные свойства на System.out - обычно гораздо удобнее сортировать их. Самый простой способ - просто "Map map = new TreeMap (свойства)"; и THEN прокручивают их, так как TreeMap возвращает отсортированные ключи.

Когда вы узнаете больше о Java, вы также увидите, что интерфейсы очень полезны при тестировании и издевательстве, поскольку вы можете создавать объекты с поведением, указанными во время выполнения, соответствующим данному интерфейсу. Продвинутый (но простой) пример можно увидеть на http://www.exampledepot.com/egs/java.lang.reflect/ProxyClass.html

Ответ 4

Если позже вы хотите изменить реализацию списка и использовать, например, LinkedList (возможно, для повышения производительности), вам не нужно менять весь код (и API, если его библиотека). если заказ не имеет значения, вы должны вернуть Collection, поэтому позже вы можете легко изменить его на "Установить", если вам нужны элементы для сортировки.

Ответ 5

Лучшее объяснение, которое я могу придумать (потому что я не программирую на Java так часто, как на других языках), заключается в том, что упростить изменение типа списка "back-end" при сохранении того же кода/интерфейса все остальное полагается. Если вы сначала объявите его как более конкретный тип, а затем решите, что хотите другого рода... если что-то случается с использованием специального метода ArrayList, эта дополнительная работа.

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

Ответ 6

Цель состоит в том, чтобы определить поведение, которое вы хотите/нуждаетесь, а затем использовать интерфейс, который обеспечивает это поведение. Это тип переменной. Затем используйте реализацию, которая отвечает вашим потребностям - эффективность и т.д. Это то, что вы создаете с помощью "нового". Эта двойственность является одной из основных идей, лежащих в основе OOD. Проблема не имеет особого значения, когда вы имеете дело с локальными переменными, но редко бывает больно следовать хорошим правилам кодирования все время.

Ответ 7

В основном это происходит от людей, которым приходится запускать большие проекты, возможно, по другим причинам - вы все это слышите. Почему, я действительно не знаю. Если вам нужен список массивов, или Hash Map или Hash Set, или что-то еще, что я не вижу смысла в устранении методов путем литья в интерфейс.

Скажем, например, недавно я узнал, как использовать и реализовывать HashSet в качестве основной структуры данных. Предположим, по какой-то причине я пошел на работу в команду. Разве этот человек не должен был знать, что данные были связаны с подходами хэширования, а не с их помощью? Вспомогательный подход, отмеченный Twisol, работает на C/С++, где вы можете разоблачить заголовки и продать библиотеку таким образом, если кто-то знает, как это сделать на Java, я бы предположил, что они будут использовать JNI - в этот момент мне кажется более простым использовать C/С++, где вы можете выставлять заголовки и создавать библиотеки с помощью установленных инструментов для этой цели.

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

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