Java接口在1.8之后發生了重大變化。所以談Java接口特點可以分為1.8版本之前和1.8版本之后。
1.8版本之前的特點:
- 接口里只能有靜態全局常量和public修飾的抽象方法。
- 為了代碼簡潔,在接口中方法可以不用public和abstract修飾,但是編譯后的方法仍然是public abstract類型的方法。全局常量也可以用public static fianl修飾,同樣編譯后仍然為public static final類型。
下面代碼演示了一個如何定義一個1.8版本之前的接口:
public interface IFlyable { String info = "靜態常量"; void fly(); }
上面代碼盡管沒有用public static final修飾info,但編譯后info為靜態全局常量,外部不能修改值。同樣fly()沒有用public abstract修飾,但編譯結果是public abstract類型。
下面是測試代碼:
1 package org.lyk.vo; 2 3 import org.lyk.intefaces.*; 4 5 public class Bird implements IFlyable 6 { 7 public void fly() 8 { 9 System.out.println("鳥兒在飛翔"); 10 } 11 }
1 package org.lyk.main; 2 3 import org.lyk.intefaces.*; 4 import org.lyk.vo.*; 5 6 public class Hello 7 { 8 public static void main(String[] args) 9 { 10 IFlyable flyAble = new Bird(); 11 flyAble.fly(); 12 System.out.println(IFlyable.info); 13 } 14 }
1.8 版本之后的特點:
- 打破了1.8之前接口里只能有全局靜態常量和public抽象方法的限制。允許接口中用default關鍵字修飾的實體方法出現(該方法在子類中可以被覆寫)
- 也允許在接口中定義public static 類型的實體函數,該靜態由接口調用。
1 package org.lyk.intefaces; 2 3 public interface IFlyable 4 { 5 public static final String info = "靜態常量"; 6 public abstract void fly(); 7 8 public static void showSomething() 9 { 10 System.out.println("這是Java1.8才支持的靜態函數,該函數只能由接口調用"); 11 } 12 13 default void printSomething() 14 { 15 System.out.println("這是Java1.8才支持的default實體函數.該方法可以在子類中被覆寫。"); 16 } 17 }
測試代碼:
1 package org.lyk.vo; 2 3 import org.lyk.intefaces.*; 4 5 public class Bird implements IFlyable 6 { 7 public void fly() 8 { 9 System.out.println("鳥兒在飛翔"); 10 } 11 12 public void printSomething() 13 { 14 System.out.println("在子類中覆寫接口方法"); 15 } 16 }
1 package org.lyk.main; 2 3 import org.lyk.intefaces.*; 4 import org.lyk.vo.*; 5 6 public class Hello 7 { 8 public static void main(String[] args) 9 { 10 IFlyable flyAble = new Bird(); 11 flyAble.fly(); 12 System.out.println(IFlyable.info); 13 14 15 flyAble.printSomething(); 16 IFlyable.showSomething(); 17 } 18 }
后記: 我想,Java1.8之所以做出如此大的設計上的改變,應該是為了向.net學習,目的是支持流(stream)。因為Java一開始設計的時候沒有考慮到stream這種場景出現,現在要在接口中增加功能,就必須打破原有限制。