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