咱們都知道在Java語言中,接口(interface)只包含方法定義而沒有具體實現,全部實現該接口的非抽象類必須提供接口方法的具體實現。讓咱們看個例子java
public interface SimpleInterface{ public void doSomeWork(); } class SimpleInterfaceImpl implements SimpleInterface{ @Override public void doSomeWork(){ System.out.println("Do Work implementation in the class"); } public static void main(String... args){ SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl(); simpObj.doSomeWork(); } }
如今,若是在SimpleInterface中添加一個新方法shell
public interface SimpleInterface { public void doSomeWork(); public void doSomeOtherWork(); }
並進行編譯,編譯器將會報以下錯誤:ide
$javac SimpleInterface.java SimpleInterface.java:18: error: SimpleInterfaceImpl is not abstract and does not override abstract method doSomeOtherWork() in SimpleInterface class SimpleInterfaceImpl implements SimpleInterface{ ^ 1 error
這種限制使得幾乎不可能對已有的接口和API進行擴展或改善。當在對Collections API加強,使其支持Java8的lambda表達式時,也遇到了一樣的挑戰。爲了克服這種限制,一個新概念被引入,咱們稱之爲默認方法(default methods)也被稱爲防護方法(defender methods)或虛擬擴展方法(virtual extension methods)
默認方法是有一些有默認的具體實現,可以幫助擴展接口的同時,避免破壞現有代碼的方法。讓咱們看下例:.net
public interface SimpleInterface { public void doSomeWork(); //A default method in the interface created using "default" keyword default public void doSomeOtherWork() { System.out.println("DoSomeOtherWorkementation in the interface"); } } class SimpleInterfaceImpl implements SimpleInterface { @Override public void doSomeWork() { System.out.println("Do Work implementation in the class"); } public static void main(String... args) { SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl(); simpObj.doSomeWork(); simpObj.doSomeOtherWork(); } }
編譯運行獲得以下輸出:翻譯
Do Some Work implementation in the class DoSomeOtherWork implementation in the interface
須要咱們注意的是當一個類實現了兩個接口而且每一個接口都聲明瞭一個一樣名稱的默認方法。這種狀況下編譯器將報錯。讓咱們用一個例子來解釋:code
public interface InterfaceWithDefaultMethod{ public void someMethod(); default public void someOtherMethod(){ System.out.println("Default implemetation in the interface"); } } public interface InterfaceWithAnotherDefMethod{ default public void someOtherMethod(){ System.out.println("Default implemetation in the interface"); } }
而後使用一個類實現上面的接口:接口
public class DefaultMethodSample implements InterfaceWithDefaultMethod, InterfaceWithAnotherDefMethod{ @Override public void someMethod(){ System.out.println("Some implemetation in the class"); } public static void main(String... args){ DefaultMethodSample def1 = new DefaultMethodSample(); def1.someMethod(); def1.someOtherMethod(); } }
編譯時報以下錯誤。 Java經過這種方式來避免究竟該調用哪一個實現的混亂。get
本文翻譯自:Introduction to Default Methods (Defender Methods) in Java 8編譯器
更深刻的瞭解Default Method請參考這裏it