原文鏈接: blog.sanaulla.info
翻譯: ImportNew.com - 黃小非
譯文鏈接: http://www.importnew.com/7302.html
我們都知道在Java語言的接口中只能定義方法名,而不能包含方法的具體實(shí)現(xiàn)代碼。接口中定義的方法必須在接口的非抽象子類中實(shí)現(xiàn)身堡。下面就是關(guān)于接口的一個(gè)例子:
public interface SimpleInterface {
public void doSomeWork();
}
class SimpleInterfaceImpl implements SimpleInterface{
@Override
public void doSomeWork() {
System.out.println("Do Some Work implementation in the class");
}
public static void main(String[] args) {
SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
simpObj.doSomeWork();
}
}
那么郭卫,如果我們?cè)赟impleInterface里面添加一個(gè)新方法政勃,會(huì)怎樣呢屈留?
public interface SimpleInterface {
public void doSomeWork();
public void doSomeOtherWork();
}
如果我們嘗試編譯上面的這段代碼,會(huì)得到如下結(jié)果:
$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
因?yàn)榻涌谟羞@個(gè)語法限制吊洼,所以要直接改變/擴(kuò)展接口內(nèi)的方法變得非常困難训貌。我們?cè)趪L試強(qiáng)化Java 8 Collections API,讓其支持lambda表達(dá)式的時(shí)候冒窍,就面臨了這樣的挑戰(zhàn)递沪。為了克服這個(gè)困難,Java 8中引入了一個(gè)新的概念综液,叫做default方法款慨,也可以稱為Defender方法,或者虛擬擴(kuò)展方法(Virtual extension methods)谬莹。
Default方法是指檩奠,在接口內(nèi)部包含了一些默認(rèn)的方法實(shí)現(xiàn)(也就是接口中可以包含方法體,這打破了Java之前版本對(duì)接口的語法限制)附帽,從而使得接口在進(jìn)行擴(kuò)展的時(shí)候埠戳,不會(huì)破壞與接口相關(guān)的實(shí)現(xiàn)類代碼。接下來蕉扮,讓我們看一個(gè)例子:
public interface SimpleInterface {
public void doSomeWork();
//A default method in the interface created using "default" keyword
//使用default關(guān)鍵字創(chuàng)在interface中直接創(chuàng)建一個(gè)default方法整胃,該方法包含了具體的實(shí)現(xiàn)代碼
default public void doSomeOtherWork(){
System.out.println("DoSomeOtherWork implementation in the interface");
}
}
class SimpleInterfaceImpl implements SimpleInterface{
@Override
public void doSomeWork() {
System.out.println("Do Some Work implementation in the class");
}
/*
* Not required to override to provide an implementation
* for doSomeOtherWork.
* 在SimpleInterfaceImpl里,不需要再去實(shí)現(xiàn)接口中定義的doSomeOtherWork方法
*/
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
以上是對(duì)default方法的一個(gè)非常簡(jiǎn)要的介紹慢显。如果有興趣的話,還可以通過看這篇文檔欠啤,來獲取更深層次的理解荚藻。
更新:
現(xiàn)在大家問得比較多的一個(gè)問題是:如果一個(gè)類實(shí)現(xiàn)了兩個(gè)接口(可以看做是“多繼承”),這兩個(gè)接口又同時(shí)都包含了一個(gè)名字相同的default方法洁段,那么會(huì)發(fā)生什么情況应狱? 在這樣的情況下,編譯器會(huì)報(bào)錯(cuò)祠丝。讓我用例子來解釋一下:
public interface InterfaceWithDefaultMethod {
public void someMethod();
default public void someOtherMethod(){
System.out.println("Default method implementation in the interface");
}
}
public interface InterfaceWithAnotherDefMethod {
default public void someOtherMethod(){
System.out.println("Default method implementation in the interface");
}
}
然后我們定義一個(gè)類疾呻,同時(shí)實(shí)現(xiàn)以上兩個(gè)接口:
public class DefaultMethodSample implements
InterfaceWithDefaultMethod, InterfaceWithAnotherDefMethod{
@Override
public void someMethod(){
System.out.println("Some method implementation in the class");
}
public static void main(String[] args) {
DefaultMethodSample def1 = new DefaultMethodSample();
def1.someMethod();
def1.someOtherMethod();
}
}
如果編譯以上的代碼,會(huì)得到一個(gè)編譯器錯(cuò)誤写半,如下所示岸蜗。因?yàn)榫幾g器不知道應(yīng)該在兩個(gè)同名的default方法中選擇哪一個(gè),因此產(chǎn)生了二義性叠蝇。