Интерфейсы в рамках коллекций - PullRequest
14 голосов
/ 22 сентября 2010

Мой вопрос

Интерфейсный набор имеет метод add(E e) и расширяет интерфейс Collection. Интерфейс Collection также имеет метод add(E e) Так зачем нам нужен тот же метод в интерфейсе Set, поскольку он уже расширяет интерфейс Collection. Какова цель? Я застрял с этим

Ответы [ 3 ]

22 голосов
/ 22 сентября 2010

Поскольку два правильных ответа не смогли убедить вас, я попытаюсь объяснить.

Интерфейсы определяют контракты - то есть они определяют , что собираются (и связывают) разработчикисделать, чтобы вы знали, что всякий раз, когда вы ссылаетесь на объект через интерфейс, он имеет строго определенное поведение, независимо от того, как именно он был реализован.

Теперь этот контрактсостоит из двух частей:

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

И вот конкретный пример Collection / Set:

  • если вы ссылаетесь на объект как Collection, то вы ничего не знаете о поведении add - позволяет ли он дублировать или нет
  • , есливы ссылаетесь на объект как Set, тогда вы уверены, что дубликаты не допускаются.

Это различие сделано javadoc из переопределенного add метод.

11 голосов
/ 22 сентября 2010

Set.add уточняет договор Collection.add.Из Javadoc последнего:

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

Это то, что сделано в Javadoc Set.add, где говорится, что, например, повторяющиеся элементы не добавляются вset.

Обновление: по контрактам и интерфейсам

(включая и расширяя мои комментарии ниже, чтобы завершить этот ответ.)

Контракт договораМетод указывает - формально или неформально - , что ожидается от вызывающей стороны в качестве входных данных для этого метода, и каков гарантированный результат вызова метода .Например, в контракте может быть указано, что никаких параметров null не ожидается, и если методу передан параметр null, он выдаст NullPointerException.Javadoc методов в среде Collection является хорошим примером таких контрактов.

Обратите внимание, что некоторые языки допускают или даже требуют формального определения контрактов , таким образом, контракты компилируются в код и активно принудительное выполнение . Eiffel - это такой язык.Однако у Java нет такой возможности; контракты, определенные в Javadoc, не являются формальными , для них даже не определен строгий формат.Они предназначены только для чтения человеком и остаются незамеченными JVM.Таким образом, нарушение контракта в Java может быть не сразу заметно , только позже, когда начнут появляться возникающие ошибки.

Контракты могут быть определены как для конкретных методов класса, так и для абстрактных / интерфейсных методов.Контракт интерфейса является (должен быть) обязательным для всех его реализаций.Т.е. HashSet.add, TreeSet.add, LinkedHashSet.add и т. Д. Все должны выполнить контракт Set.add (и могут дополнительно его усовершенствовать).Реализация, которая не работает в соответствии с контрактом Set.add, нарушает принцип подстановки Лискова .

3 голосов
/ 22 сентября 2010

Насколько я знаю, расширенные классы должны иметь те же методы, которые указаны суперклассом. Что касается различий между методами добавления, я предлагаю вам сравнить javadocs для соответствующих add() s

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