2010-10-20 6 views
20

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

Например, Set redeclares это:

/** 
* Returns the number of elements in this set (its cardinality). If this 
* set contains more than <tt>Integer.MAX_VALUE</tt> elements, returns 
* <tt>Integer.MAX_VALUE</tt>. 
* 
* @return the number of elements in this set (its cardinality) 
*/ 
int size(); 

/** 
* Returns <tt>true</tt> if this set contains no elements. 
* 
* @return <tt>true</tt> if this set contains no elements 
*/ 
boolean isEmpty(); 

И декларация в Collection:

/** 
* Returns the number of elements in this collection. If this collection 
* contains more than <tt>Integer.MAX_VALUE</tt> elements, returns 
* <tt>Integer.MAX_VALUE</tt>. 
* 
* @return the number of elements in this collection 
*/ 
int size(); 

/** 
* Returns <tt>true</tt> if this collection contains no elements. 
* 
* @return <tt>true</tt> if this collection contains no elements 
*/ 
boolean isEmpty(); 

Это кажется очень избыточными для меня. Почему бы не просто определить интерфейс Set как:

public interface Set<E> extends Collection<E> {} 

Я думаю, что нет ни одного различия между этими интерфейсами, не так ли?


Конечно, я не спрашиваю о другом семантикой/значении Set. Я знаю это. Я просто спрашиваю, имеет ли это технически (т. Е. Компилятору) какую-либо разницу. Т.е., вообще говоря:

interface A { void foo(); } 
interface B extends A { void foo(); } 
interface C extends A {} 

Теперь, есть ли разница между A, B или C?


Хотя контракт (т.е. то, что сказано в документации) действительно может быть различным для некоторых функций (как для add), есть веская причина, чтобы переопределить их: Для того, чтобы иметь возможность поставить новую документацию, т.е. определить новый контракт.

Однако есть также функции (например, isEmpty), которые имеют точно такую ​​же документацию/контракт. Почему они также переоформлены?

+1

Я буду голодать, пока это не будет рассмотрено! – willcodejavaforfood

+0

вам нужно понять, что интерфейс не является серебряной пулей. в интерфейсе вы не можете понять последовательность или неинвариант, который был проведен любым классом в java. эта проблема является открытой проблемой, которую разработчики Java решили решить, указав ответ в руководстве. если у вас есть лучшее решение, представление в языке syntex sequnce и инвариантов, здесь есть место, чтобы заявить об этом. – none

+0

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

ответ

11

Технически для компилятора это не имеет никакого значения.

Однако набор не может иметь повторяющиеся записи, тогда как коллекция может. Об этом стоит знать.

Из-за этого семантика методов для параметров, возвращаемых значений и событий может означать разные вещи. Redeclaring также позволяет javadoc стать более конкретным.Например, для добавления():

Set: @return верно, если этот набор уже не содержат указанный элемент

Коллекция: @return верно, если эта коллекция изменилась в результате вызова

The значение для множества более конкретно.

Даже для методов, которые не являются более конкретными, это позволяет javadoc быть более приятным. Например, для size(): «Возвращает количество элементов в этом наборе (его мощность)». который ближе к языку, который люди, привыкшие к математическим наборам, поймут.

В документах API обобщается это: «Интерфейс« Установка »устанавливает дополнительные условия, помимо тех, что унаследованы от интерфейса Collection, от контрактов всех конструкторов и контрактов методов add, equals и hashCode. другие удобства унаследованы также для удобства. (Спецификации, прилагаемые к этим объявлениям, были адаптированы к интерфейсу Set, но они не содержат каких-либо дополнительных условий.) «

+0

Я не думаю, что это был вопрос. Вопрос в том, почему идентичные методы обновляются (например, 'size' и' isEmpty'). – musiKk

+0

@musiKk - спасибо, я думал, что упомянул об этом, но я постарался быть более конкретным сейчас –

+1

Ах, поэтому основные причины (для большинства функций) и основной ответ на мой вопрос: «он позволяет javadoc чтобы быть красивее ». Это то, что я предположил, но я спросил здесь о том, чтобы просто быть уверенным в этом. – Albert

9

Ответ представлен в API java6 для набора.

«Интерфейс« Установка »устанавливает дополнительные условия, помимо тех, что унаследованы от интерфейса Collection, от контрактов всех конструкторов и контрактов методов add, equals и hashCode. Объявления для других унаследованных методов также включены сюда для удобства . (Спецификации, прилагаемые к этим объявлениям, были адаптированы к интерфейсу Set, но они не содержат никаких дополнительных условий.) «

+0

Ах, так или иначе, прочитайте это. Но просто для уточнения: Технически, это не имеет никакого значения?Это только то, что IDE показывают несколько другую документацию некоторых функций для разработчика? – Albert

+0

@Albert, что не имеет значения? Есть все различия в мире, потому что семантика Set отличается от семантики семантики, отличной от семантики семпла и т. Д. – hvgotcodes

+0

@hvgotcodes: Техническая разница = существующий рабочий код сломается, если вы используете определение 'Set' – Albert

6

Существует больше способа, чем его подпись.

В этом случае документация этих методов была адаптирована к наборам с точки зрения пред- и пост-условий и терминологии.

+1

+1 для «Существует больше метода, чем его подпись». –

2

Они переоформлены, потому что, даже если имена одинаковы, они имеют различный смысл. Метод add в Set представляет собой конкретный вариант общего метода add в Collection.

Целью является прямое указание, что метод add os Set сильно отличается от метода добавления Collection.

Почему бы не просто определить интерфейс Установить как:

public interface Set<E> extends Collection<E> {} 

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

+0

Но контракт - это просто документация, не так ли? Так технически, это не имело бы никакого значения? Просто другие разработчики знают о другом значении? – Albert

+0

_Technically_, как чистый код, нет никакой разницы. _Iто просто другие разработчики знают о различном значении? _: Да. И это очень важно. – Nivas

+1

Хорошо, спасибо за это разъяснение. Тем не менее вопрос остается открытым: как насчет действительно идентичных функций, таких как 'isEmpty' или' size'? Почему они переодеваются? – Albert

Смежные вопросы