Java 8 接口里的默认方法特性

xnqt3116 8年前
   <p>这篇文章我们将要探讨Java 8中接口里的默认方法特性。Java8指出“默认方法使得新功能被添加到库中的接口里面,同时又能保证与这些接口老版本代码的二进制兼容性。</p>    <p>这些年Java进化升级了很多,在Java库中引入的接口需要添加新的功能。在没有默认方法特性时,当你往接口中添加新方法时,接口内部所有实现的类都要历经一些修改。这将导致上千行的代码修改工作量。为了避免这点,Java 8引入了默认对象方法。亦即,如果你想要往现存的接口中添加任何功能,你只需添加默认方法特性而不会影响接口实现形式。</p>    <p>让我们看一些例子来更好的理解它。例如,我声明了一个具有打开和读取功能的接口“BookIterface”。接口的类需要实现打开和读取方法。</p>    <pre>  <code class="language-java">package org.smarttechie;    /**   * The interface is intended to open and read. The implementors should   * implement the methods to open and read.   *    * @author Siva Prasad Rao Janapati   *   */  public interface BookInterface {   /**    * The method opens the book    */   public void openTheBook();     /**    * The method reads the book    */   public void readTheBook();  }  </code></pre>    <p>现在,我们提供上面接口的实现代码。</p>    <pre>  <code class="language-java">package org.smarttechie;    /**   * The JavaBookImpl is the implementation of BookInterface   *    * @author Siva Prasad Rao Janapati   *   */  public class JavaBookImpl implements BookInterface {   /**    * This opens the book    */   @Override   public void openTheBook() {    System.out.println("The Java book is opened");   }     /**    * This reads the book    */   @Override   public void readTheBook() {    System.out.println("Reading the Java book");   }  }</code></pre>    <p>现在,我们想要给接口提供一个关闭功能。如果你直接添加关闭功能到book接口中,现存的实现类需要历经一些修改。有了默认方法特性后,我们能给book接口直接添加关闭功能。默认方法对所有实现都可用。</p>    <pre>  <code class="language-java">package org.smarttechie;    /**   * The interface is intended to open and read. The implementors should   * implement the methods to open and read.   *    * @author Siva Prasad Rao Janapati   *   */  public interface BookInterface {   /**    * The method opens the book    */   public void openTheBook();     /**    * The method reads the book    */   public void readTheBook();      /**   * The default method implementation   */   public default void closeTheBook() {    System.out.println("Closting the book");   }  }</code></pre>    <pre>  <code class="language-java">package org.smarttechie;    /**   * The JavaBookImpl is the implementation of BookInterface   *    * @author Siva Prasad Rao Janapati   *   */  public class JavaBookImpl implements BookInterface {   /**    * This opens the book    */   @Override   public void openTheBook() {    System.out.println("The Java book is opened");   }     /**    * This reads the book    */   @Override   public void readTheBook() {    System.out.println("Reading the Java book");   }     public static void main(String[] args) {    BookInterface bookInter = new JavaBookImpl();    // Call the default method declared in BookInterface    bookInter.closeTheBook();    JavaBookImpl book = new JavaBookImpl();    book.closeTheBook();   }  }</code></pre>    <p>下面给出了上述调用方法的字节码。从字节码中,我们可以认为默认方法是一种“虚方法”。</p>    <p><img alt="Java 8 接口里的默认方法特性" src="https://simg.open-open.com/show/dfc902fee0e28f23d71b52815dba11f0.png" width="605" height="187"></p>    <p>如果你想,你可以重载实现类中的默认方法:</p>    <pre>  <code class="language-java">package org.smarttechie;    /**   * The JavaBookImpl is the implementation of BookInterface   *    * @author Siva Prasad Rao Janapati   *   */  public class JavaBookImpl implements BookInterface {   /**    * This opens the book    */   @Override   public void openTheBook() {    System.out.println("The Java book is opened");   }     /**    * This reads the book    */   @Override   public void readTheBook() {    System.out.println("Reading the Java book");   }     /*    * This closes the book    */   public void closeTheBook() {    System.out.println("Closing the JAVA book");   }     public static void main(String[] args) {    BookInterface book = new JavaBookImpl();    book.closeTheBook();   }  }</code></pre>    <p>到这会儿,你可能有一个疑问,如果我们实现了两个具有同样默认方法签名的接口会怎样?在那种情况下,调用实现会得到下面的编译错误提示。</p>    <blockquote>     <p>“用参数()和()复制名为closedTheBook的默认方法是继承于TheBookInterface和BookInterface的类型。”</p>    </blockquote>    <pre>  <code class="language-java">package org.smarttechie;    public interface TechBookInterface {    /**    * The default method implementation    */   public default void closeTheBook() {    System.out.println("Closing the book");   }  }</code></pre>    <pre>  <code class="language-java">package org.smarttechie;    /**   * The JavaBookImpl is the implementation of BookInterface   *    * @author Siva Prasad Rao Janapati   *   */  public class JavaBookImpl implements BookInterface, TechBookInterface {   /**    * This opens the book    */   @Override   public void openTheBook() {    System.out.println("The Java book is opened");   }     /**    * This reads the book    */   @Override   public void readTheBook() {    System.out.println("Reading the Java book");   }     public static void main(String[] args) {    BookInterface book = new JavaBookImpl();    book.closeTheBook();   }  }</code></pre>    <p>为了避免这个编译错误,我们需要在实现类中显式地定义那个具有同样签名的方法。</p>    <pre>  <code class="language-java">package org.smarttechie;    /**   * The JavaBookImpl is the implementation of BookInterface   *    * @author Siva Prasad Rao Janapati   *   */  public class JavaBookImpl implements BookInterface, TechBookInterface {   /**    * This opens the book    */   @Override   public void openTheBook() {    System.out.println("The Java book is opened");   }     /**    * This reads the book    */   @Override   public void readTheBook() {    System.out.println("Reading the Java book");   }     public void closeTheBook() {    System.out.println("Closing the JAVA book");   }     public static void main(String[] args) {    BookInterface book = new JavaBookImpl();    book.closeTheBook();   }  }</code></pre>    <p>更深入的了解阅读,可以参考下面的链接:</p>    <ul>     <li><a href="/misc/goto?guid=4959638966714068299">https://jcp.org/en/jsr/detail?id=335</a></li>     <li><a href="/misc/goto?guid=4958970912859213006">https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html</a></li>    </ul>    <p> </p>    <p>来源:<a href="/misc/goto?guid=4959671433923949755">码农网</a></p>