咱们都知道在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