Java:设置接口和Collection接口的差异

我只是查看了Set界面,发现它主要(或完全)只重新声明已经在Collection接口中的函数。 Set自己扩展Collection ,那么这是不是意味着Set界面自动拥有Collection所有function? 那么他们为什么要重新申报呢?

例如, Set redeclares this:

 /** * Returns the number of elements in this set (its cardinality). If this * set contains more than Integer.MAX_VALUE elements, returns * Integer.MAX_VALUE. * * @return the number of elements in this set (its cardinality) */ int size(); /** * Returns true if this set contains no elements. * * @return true if this set contains no elements */ boolean isEmpty(); 

Collection的声明:

 /** * Returns the number of elements in this collection. If this collection * contains more than Integer.MAX_VALUE elements, returns * Integer.MAX_VALUE. * * @return the number of elements in this collection */ int size(); /** * Returns true if this collection contains no elements. * * @return true if this collection contains no elements */ boolean isEmpty(); 

这对我来说似乎很多余。 为什么不将Set接口定义为:

 public interface Set extends Collection {} 

我认为这些接口之间没有任何区别,对吧?


当然,我不是在询问Set的不同语义/含义。 我知道。 我只是询问技术上(即编译器)是否有任何区别。 即,一般来说:

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

现在, ABC之间有什么区别吗?


虽然合同(即文档中所说的内容)对于某些function(如add )确实可能有所不同,但有正当理由重新声明它们:能够提供新文档,即定义新合同。

但是,还有一些function(如isEmpty )具有完全相同的文档/合同。 他们为什么还重新申报?

从技术上讲,它对编译器没有任何影响。

但是,一个集合不能有重复的条目,而集合可以。 这是值得了解的。

因此,参数,返回值和发生的事情的方法语义可能意味着不同的东西。 Redeclaring还允许javadoc变得更具体。 例如对于add():

设置:@return如果此集合尚未包含指定的元素,则为true

集合:@return如果此集合因调用而更改,则为true

set的含义更具体。

即使对于不具体的方法,它也可以使javadoc更好。 例如,对于size():“返回此集合中的元素数量(其基数)。” 这更接近人们用于数学集的语言将理解。

API文档总结了这一点: “Set接口在所有构造函数的契约和add,equals和hashCode方法的契约上放置了除Collections接口inheritance的那些之外的其他规定。其他inheritance方法的声明也是为方便起见,此处包括在内。(这些声明附带的规范是根据Set界面量身定制的,但它们不包含任何其他规定。)“

答案在java6 API for set中。

“Set接口在所有构造函数的合同以及add,equals和hashCode方法的契约上放置了除Collections接口inheritance的附加规定之外的其他规定。为方便起见,此处还包含其他inheritance方法的声明。(规范)随附这些声明是根据Set界面量身定制的,但它们不包含任何其他规定。)“

方法比签名更多​​。

在这种情况下,这些方法的文档已根据前后条件和术语定制。

它们被重新声明,因为即使名称相同,它们也有不同的含义。 Set中的add方法是Collectiongenericsadd方法的特定实现。

目的是明确指定Set的add方法与Collection的add方法非常不同。

为什么不将Set接口定义为:

 public interface Set extends Collection {} 

如果以这种方式完成,就没有可以指定Set地方。 我怎么知道通过实现Setadd方法,我不应该允许重复?