在研究Collection接口源码时,发现Collection接口继承了Iterable接口,并使用了default关键字。

default关键字

default方法是在java8中引入的关键字,也可称为Virtual extension methods——虚拟扩展方法。是指,在接口内部包含了一些默认的方法实现(也就是接口中可以包含方法体,这打破了Java之前版本对接口的语法限制),从而使得接口在进行扩展的时候,不会破坏与接口相关的实现类代码。

Iterable接口有三个方法,分别是iterator()、forEach(Consumer<? super T> action)、spliterator()。其中第二个与第三个方法均使用了default关键字修饰。

    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
以上两个方法采用了default关键字修饰,从而在接口中就直接实现了对方法的实现。再实现含有default方法的接口时,我们可以直接使用接口的default方法,也可以在实现类中重写接口的default方法从而实现自己的方法。
比如:

    interface I1 {
        void test1();
        void test2();
 
        default void test3(){
            System.out.println("sss1");
        }
    }
 
    interface I2 extends I1 {
 
        @Override
        default void test3(){
            System.out.println("sss2");
        }
    }
 
    class C2 implements I1, I2{
 
 
        @Override
        public void test1() {
 
        }
 
        @Override
        public void test2() {
 
        }
 
        @Override
        public void test3() {
            System.out.println("sss3");
        }
 
    }

在Collection接口中,Collection接口继承了Iterable接口的同时,还重写了Iterable接口的iterator()方法与default Spliterator<E> spliterator()方法。(在这里笔者有个疑问,既然已经继承了Iterable接口,为什么还要重写Iterable接口的iterator()方法,除了注释不同,给人们不同理解之外,还有没有其他用途?集合接口中有大量类似情景,如Set接口在继承Collection接口的同时,还重写了大量Collection接口已有方法,如:size()等。是出于不改动原有接口(只增不改)的目的吗?请大家评论。)