Java:设置接口和集合接口的区别
问题内容:
我只是查看了Set
接口,发现它主要(或完全)仅重新声明了Collection
接口中已经存在的函数。Set
本身可以扩展Collection
,这是否意味着Set
接口自动具有的所有功能Collection
?那么为什么要重新宣布呢?
例如,Set
重新声明:
/**
* 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
)具有完全相同的文档/合同。为什么还要重新申报?
问题答案:
从技术上讲,对于编译器而言,它没有任何区别。
但是,集合不能有重复的条目,而集合可以有。这是值得了解的。
因此,参数,返回值和发生的情况的方法语义可能意味着不同的含义。重新声明还可以使javadoc更加具体。例如add():
设置:@return如果此设置尚未包含指定的元素,则为true
集合:@return如果此集合由于调用而发生更改,则返回true
set的含义更具体。
即使对于不具体的方法,它也使javadoc变得更好。例如,对于size():“返回此集合中的元素数(其基数)。”
这更接近人们习惯于数学集合的语言所能理解的语言。
API文档对此进行了总结:
“除从Collection接口继承的那些规定外,Set接口还对所有构造函数的协定以及add,equals和hashCode方法的协定附加了其他规定。其他继承方法的声明也为方便起见,将其包括在此处。(这些声明所附带的规范是针对Set接口定制的,但不包含任何其他规定。)”