List 接口继承自 Collection 接口, 那么 实现 List 接口的类, 就算 List 中没有声明 iterator( ) 方法 , 也会因为 Collection 中 已经声明了 ,而必须实现 iterator 方法啊? 为啥 List 中 又 声明了一个和Colleciton 接口一样的 iterator( ) 方法 ?
public interface Iterable<T> {
Iterator<T> iterator();
}
自己写了接口和实现类试了一下,确实既然接口的public方法会默认继承,貌似再写一遍没什么功能性。
写不写都不影响,我看了唯一不同的就是方法注释上写的是操作相对应的集合。
大可能是为了在JDK更新前后使用的时候程序员能更清晰知道它“拥有”什么方法吧。而不用一层一层往上找到超类才知道原来它们都拥有这个方法。
Java的List接口是继承自Collection接口的,它们都具有iterator()方法,因为在集合框架中,迭代器是用来遍历集合中的元素的一个重要工具,它可以遍历集合中的所有元素,而不需要暴露集合内部的实现细节。
在Collection接口中,iterator()方法是用来返回一个Iterator对象,该对象可以用于遍历集合中的所有元素。而List接口是Collection接口的一个子接口,它继承了Collection接口中的所有方法,包括iterator()方法。
List接口中的iterator()方法返回的Iterator对象,可以用于遍历List中的所有元素,包括通过下标索引访问的元素以及使用迭代器遍历访问的元素。此外,List接口还提供了一些其他的访问元素的方法,如get(int index)、set(int index, E element)等,这些方法可以通过下标索引来访问List中的元素。
因此,List接口中的iterator()方法和Collection接口中的iterator()方法本质上是相同的,都是用来遍历集合中的元素。但是由于List接口具有额外的访问元素的方法,因此List接口中的Iterator对象可以用来访问List中的所有元素,包括使用下标索引访问的元素和使用迭代器访问的元素。
华生,首先恭喜你发现了盲点!
如果单纯从代码上看,List接口和Collection接口的iterator方法都是多余,因为它们都是从Iterable来的。
但是你再去细看一下这几个接口的iterator方法的注释就很容易理解了,Collection的iterator方法的注释上对返回的迭代器的顺序是没有具体要求的,这个行为交给子接口或者子类去定义,就是说Collection定义的是一种很宽松的行为。
再看List接口的iterator方法的注释,它要求返回的迭代器的元素是要按照一定的顺序排序的,这个行为已经是收紧了,所以你可以看到List有两个常见的子类ArrayList和LinkedList的迭代器是有顺序的。
再看Collection接口的另一个重要的子接口Set,Set接口的iterator方法就明确写着元素不需要特别的顺序,就是你怎么方便怎么来。
这就是继承和多态的一种典型的应用——表现不同的行为。但因为你定义的是接口,我们都知道接口是高度抽象的,所以需要给使用者明确写清楚应该遵守什么规则的行为。
这个问题,本质是duck-typing思想的一种体现,理解了这个概念,估计不会有这样的疑问,同样的接口有
Comparable:
Serializable:
假设以Comparable为例,父类在进行比较时,会抽象成为公共的,而具体到某个子类时,会具体到只适用于这个子类。当然子类可以不实现,但是当子类更具体化之后,往往会根据其特点提供具体的实现。