集合框架中的接口

时间:2010-09-22 09:11:59

标签: java collections

我的问题是

接口集具有方法add(E e),它扩展了接口Collection。 接口Collection也有方法add(E e) 那么为什么我们在接口集中需要相同的方法,因为它已经扩展了接口Collection。 什么目的 ? 我坚持认为

3 个答案:

答案 0 :(得分:22)

由于这两个正确答案无法说服你,我会试着解释一下。

接口定义契约 - 即它们定义实现者要进行(和绑定)的内容,以便您知道无论何时通过接口引用对象,它都具有严格定义的行为,无论如何实施它。

现在,这份合同分为两部分:

  • 方法签名 - 方法签名是编译器强制执行的元素 - 所有实现者必须符合接口定义的所有方法签名
  • 记录的行为 - 当方法比方法签名更多时,记录特殊行为。它再次告诉客户端接口对所有实现者的期望,尽管它在技术上并没有强制实现者遵守它。

以下是具体的Collection / Set示例:

  • 如果您将某个对象称为Collection,那么您不知道add的任何行为 - 是否允许重复
  • 如果您将对象称为Set,那么您确定不允许重复。

这种区别是由重新定义的 add方法的 javadoc 完成的。

答案 1 :(得分:11)

Set.add完善了Collection.add的合同。来自后者的Javadoc:

  

支持此操作的集合可能会限制可能添加到此集合的元素。特别是,某些集合将拒绝添加null元素,而其他集合将对可能添加的元素类型施加限制。集合类应在其文档中明确指出可以添加哪些元素的任何限制。

这就是在Set.add的Javadoc中所做的事情,其中​​指出了重复的元素不会添加到集合中。

更新:合同和接口

(包括并扩展我的评论以完善这个答案。)

方法的契约指定 - 正式或非正式 - 调用者应该作为该方法的输入提供什么,以及方法调用的保证结果是什么。例如。合同可能声明没有预期的null参数,如果方法传递了null参数,它将抛出NullPointerException。 Collection框架中的Javadoc方法就是这种合同的好例子。

请注意,某些语言允许甚至需要合同的正式定义,因此合同会被编译到代码中并且主动强制执行Eiffel就是这样一种语言。但是,Java没有这样的设施; Javadoc中定义的合同不是正式的,甚至没有为它们定义严格的格式。这些仅用于人类阅读,而不被JVM忽视。因此,在Java中违反合同可能不会立即引起注意,只有在结果错误开始出现后才会发生。

可以为具体类方法和抽象/接口方法定义合同。接口的契约(应该)绑定到它的所有实现。即HashSet.addTreeSet.addLinkedHashSet.add等所有人都必须履行Set.add的合同(并可能进一步完善)。根据{{​​1}}的合同行为不符合的实施会破坏Liskov substitution principle

答案 2 :(得分:3)

据我所知,扩展类应该具有超类指定的相同方法。至于添加方法之间的差异,我建议你比较相应的add() s的javadoc