接口的常規實現方式
熟悉java接口的同學都知道,接口被某些類實現后,一旦在接口中增加了新方法,那么實現該接口的所有類都要實現這個新增的方法(即使這個新增的接口對某些類沒有用處)。
定義一個接口
- public interface IDemo {
- void func1();
- }
類CDemo1實現接口IDemo
- public class CDemo1 implements IDemo{
- @Override
- public void func1() {
- }
- }
類CDemo2實現接口IDemo
- public class CDemo2 implements IDemo{
- @Override
- public void func1() {
- }
- }
在IDemo中新增加方法func2()
- public interface IDemo {
- void func1();
- void func2();
- }
可以看到CDemo1和CDemo2中需要強制實現方法func2(),如下圖所示:


接口中的default
上面的實例導致了前面提出的那個問題,一旦在接口中增加了新方法,那么已經實現了該接口的所有的類都要實現這個新增的方法!那么,如果是JDK中的某個核心接口需要變更,需要新增某些方法呢?這個工作量更是可想而知,我們來看一下java.util.Collection這個接口,它在jdk1.7中的方法包括:

而在JDk 1.8中 Collection接口中包括方法如下:

其中新增的接口,都用default來修飾(jdk1.7升級到jdk1.8后,接口的重要變化),源代碼如下:
- default Stream<E> stream() {
- return StreamSupport.stream(spliterator(), false);
- }
- default Stream<E> parallelStream() {
- return StreamSupport.stream(spliterator(), true);
- }
- default Spliterator<E> spliterator() {
- return Spliterators.spliterator(this, 0);
- }
- default boolean removeIf(Predicate<? super E> filter) {
- Objects.requireNonNull(filter);
- boolean removed = false;
- final Iterator<E> each = iterator();
- while (each.hasNext()) {
- if (filter.test(each.next())) {
- each.remove();
- removed = true;
- }
- }
- return removed;
- }
我們不僅大吃一驚,這還是我們熟知的接口嗎?接口中的方法居然有了實現代碼!吃驚過后,我們來想想作者的意圖。還是上面的代碼,我們新增方法func3(),并完成簡單的實現
- public interface IDemo {
- void func1();
- void func2();
- default void func3(){
- System.out.println("this is default func2");
- }
- }
然后查看類CDemo1,一切正常,沒有任何錯誤提示:

實例化CDemo1后,可以正常調用func3方法,代碼如下:
- public static void main(String[] args) {
- CDemo1 cd1=new CDemo1();
- cd1.func3();
- }
讀到這里發現接口中通過default關鍵字來進行接口實現的好處了吧,簡單四個字就是 “方便擴展” !通過這個技術可以做到在接口中新增加方法并且不會影響到已經實現了該接口的所有的類!包括jdk1.8新引入的Lambda表達式也是基于這一知識點來實現的!
接口中的static
與此同時,從jdk1.8開始,接口中可以通過static關鍵字來修飾方法,同樣可以對方法進行實現
- static void func4(){
- System.out.println("this is static func4");
- }
調用方法也非常的簡單,接口.static 方法,例如:
- IDemo.func4();
大家可以這樣理解,接口中的static方法可以作為工具方法來提供給大家進行方便調用!
原文鏈接:https://www.toutiao.com/a7049532812554355238/