Java 8新特性——default方法(defenece方法)介紹

jopen 11年前發布 | 23K 次閱讀 Java Java開發

我們都知道在Java語言的接口中只能定義方法名,而不能包含方法的具體實現代碼。接口中定義的方法必須在接口的非抽象子類中實現。下面就是關于接口的一個例子:

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(); } }</pre>




那么,如果我們在SimpleInterface里面添加一個新方法,會怎樣呢?

public interface SimpleInterface {
  public void doSomeWork();
  public void doSomeOtherWork();
}




如果我們嘗試編譯上面的這段代碼,會得到如下結果:

$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




因為接口有這個語法限制,所以要直接改變/擴展接口內的方法變得非常困難。我們在嘗試強化Java 8 Collections API,讓其支持lambda表達式的時候,就面臨了這樣的挑戰。為了克服這個困難,Java 8中引入了一個新的概念,叫做default方法,也可以稱為Defender方法,或者虛擬擴展方法(Virtual extension methods)。

Default方法是指,在接口內部包含了一些默認的方法實現(也就是接口中可以包含方法體,這打破了Java之前版本對接口的語法限制),從而使得接口在進行擴展的時候,不會破壞與接口相關的實現類代碼。接下來,讓我們看一個例子:

public interface SimpleInterface {
  public void doSomeWork();

  //A default method in the interface created using "default" keyword
  //使用default關鍵字創在interface中直接創建一個default方法,該方法包含了具體的實現代碼
  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里,不需要再去實現接口中定義的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




以上是對default方法的一個非常簡要的介紹。如果有興趣的話,還可以通過看這篇文檔,來獲取更深層次的理解。

更新:

現在大家問得比較多的一個問題是:如果一個類實現了兩個接口(可以看做是“多繼承”),這兩個接口又同時都包含了一個名字相同的default方法,那么會發生什么情況? 在這樣的情況下,編譯器會報錯。讓我用例子來解釋一下:

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");
  }
}




然后我們定義一個類,同時實現以上兩個接口:

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();
  } 
}




如果編譯以上的代碼,會得到一個編譯器錯誤,如下所示。因為編譯器不知道應該在兩個同名的default方法中選擇哪一個,因此產生了二義性。

原文鏈接: blog.sanaulla.info 翻譯: ImportNew.com - 黃小非
譯文鏈接: http://www.importnew.com/7302.html

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!