我的问题是
接口集具有方法add(E e)
,它扩展了接口Collection
。
接口Collection
也有方法add(E e)
那么为什么我们在接口集中需要相同的方法,因为它已经扩展了接口Collection
。
什么目的 ?
我坚持认为
答案 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.add
,TreeSet.add
,LinkedHashSet.add
等所有人都必须履行Set.add
的合同(并可能进一步完善)。根据{{1}}的合同行为不符合的实施会破坏Liskov substitution principle。
答案 2 :(得分:3)
据我所知,扩展类应该具有超类指定的相同方法。至于添加方法之间的差异,我建议你比较相应的add()
s的javadoc