在研究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()等。是出於不改動原有接口(只增不改)的目的嗎?請大家評論。)