【发布时间】:2011-04-28 01:45:15
【问题描述】:
我刚刚查看了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)具有完全相同的文档/合同。为什么还要重新声明?
【问题讨论】:
-
我会进行绝食,直到这件事情得到解决!
-
你要明白界面没有灵丹妙药。在接口中,您无法理解序列,也无法理解 java 中任何类所拥有的不变量。这个问题是一个开放的问题,Java 开发人员决定通过在手册中说明答案来解决。如果你有更好的解决方案,用语言语法表示序列和不变量,这里是一个说明它的地方。
-
@none:嗯,这并不是我提出问题的目的,但这确实是另一个非常有趣的问题。我看到了一些建议,可以为函数编写复杂的逻辑前置条件和后置条件。不过我已经不记得它叫什么了。
-
@pre 和@post 的问题在于它们不会让您知道指令的顺序。让我们简单看一下迭代器模式,他们必须制作一个特殊的语法以使所有人都清楚,并确保正确调用 hasNext() 和 Next() 接口。那么解决方案是通过提供手册并为每个问题创建新的语言语法吗? lisp 是答案(你写的代码写的代码……)我希望不是。
标签: java collections interface set