Java:设置接口和集合接口的差异

Java:设置接口和集合接口的差异,java,collections,interface,set,Java,Collections,Interface,Set,我只是查看了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_V

我只是查看了
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();
这对我来说似乎是多余的。为什么不将
Set
接口定义为:

public interface Set<E> extends Collection<E> {}
public interface Set<E> extends Collection<E> {} 
现在,在
A
B
C
之间有什么区别吗


虽然合同(即文档中所述内容)对于某些功能(如
add
)可能确实有所不同,但有一个重新声明它们的正当理由:能够放置新文档,即定义新合同


但是,也有一些函数(如
isEmpty
)具有完全相同的文档/契约。为什么还要重新声明呢?

答案在set的java6 API中


Set接口在所有构造函数的约定以及add、equals和hashCode方法的约定上,除了从Collection接口继承的约定之外,还添加了其他约定。为了方便起见,这里还包含了其他继承方法的声明。(这些声明附带的规范已针对Set接口进行了定制,但它们不包含任何附加规定。)“

从技术上讲,对于编译器来说,这一点都没有区别

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

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

Set:@如果此集合尚未包含指定元素,则返回true

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

set的含义更为具体

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


API文档对此进行了总结:“集合接口在所有构造函数的契约以及add、equals和hashCode方法的契约上,除了从集合接口继承的那些之外,还对其他继承方法的声明进行了附加规定。为了方便起见,这里还包括了其他继承方法的声明。(这些声明随附的规范已针对Set接口进行了定制,但它们不包含任何附加规定。)“

方法不仅仅是其签名


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

它们被重新声明,因为即使名称相同,它们也有不同的含义。
集合中的
add
方法是中泛型
add
方法的具体实现
收藏

其目的是明确指定
集合的
添加
方法与
集合的添加方法非常不同

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

public interface Set<E> extends Collection<E> {}
public interface Set<E> extends Collection<E> {} 
公共接口集扩展集合{}

如果这样做,就没有地方可以指定
集合
的合同。我怎么知道通过实施
集合
添加
方法,我不应该允许重复?

我会绝食,直到这件事得到解决!你必须明白界面不是银bullet。在接口中,您无法理解java中任何类所持有的序列和不变量。这个问题是一个开放的问题,java开发人员决定通过在手册中说明答案来解决。如果您有更好的解决方案,用syntex语言表示sequence和不变量,这里有一个地方可以说明。@none:嗯,这不完全是我的问题的目的,但这确实是另一个非常有趣的问题。我看到一些建议,其中有可能为函数编写复杂的逻辑前置和后置条件。不过,我已经记不清它被称为什么了。@pre和@post的问题是它们不让您知道指令序列。让我们简单地看一下迭代器模式,他们必须制作一个特殊的sytax来让所有人都清楚,并确保正确调用hasNext()和Next()接口。解决方案是为每个问题提供一个手册并创建新的语言语法吗?lisp就是答案吗(你写的代码写的代码是…)我不希望。我不认为这是问题。问题是为什么相同的方法会被重新声明(比如
size
isEmpty
)。@musiKk-谢谢,我想我已经提到过了,但我现在已经尝试更具体了,所以,主要原因(对于大多数函数)我的问题的基本答案是:“它使javadoc变得更好”:这就是我的假设,但我在这里问了一下,只是为了确定这一点。@Albert:这不仅仅是让Javadoc变得更好……语义上的差异造成了功能上的差异,并且有一个表示
Set
的单独接口使您能够将给定的方法限制为只处理符合的集合e> 通过简单地声明
Set
而不是
Collection
作为参数类型,以类型安全的方式设置
语义。@ColinD:我知道不同的含义。但编译器仍然没有区别。即,只有Javadoc是d