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 {}
现在, A
, B
或C
之间有什么区别吗?
虽然合同(即文档中所说的内容)对于某些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
方法是Collection
genericsadd
方法的特定实现。
目的是明确指定Set
的add方法与Collection
的add方法非常不同。
为什么不将Set接口定义为:
public interface Set extends Collection {}
如果以这种方式完成,就没有可以指定Set
地方。 我怎么知道通过实现Set
的add
方法,我不应该允许重复?