JDK8之前,interface中可以定義常量和抽象方法,訪問修飾符是public。
public interface A { /** a1和a2寫法是等價的 */ public static final int a1 = 0; int a2 = 0; /** methodA1和methodA2寫法是等價的 */ public abstract void methodA1(); void methodA2(); }
JDK8起,允許我們在interface中使用static和default修飾方法(使用這兩種修飾符中其一就不能使用abstract修飾符),從而方法具有方法體。
public interface A { /** default訪問修飾符修飾的方法 */ default void methodB1() { System.out.println("this is default method"); } /** static修飾符修飾的方法 */ public static void methodB2() { System.out.println("this is static method"); } }
default修飾的方法,通過接口的實現類的對象調用;static修飾的方法,直接通過接口名調用。
public class Test implements A{ public static void main(String[] args) { /** 接口的default方法,通過接口的實現類的對象調用 */ Test test = new Test(); test.methodB1(); /** 接口的靜態方法,通過接口名調用 */ A.methodB2(); } }
由於java支持一個實現類可以實現多個接口,如果多個接口中存在同樣的static和default方法會怎么樣呢?
- 如果有兩個接口中的static方法一模一樣,並且實現類同時實現了這兩個接口,此時並不會產生錯誤,因為jdk8只能通過接口類調用接口中的靜態方法,所以對編譯器來說是可以區分的。
- 如果兩個接口中定義了一模一樣的default方法,並且一個實現類同時實現了這兩個接口,那么必須在實現類中重寫默認方法,否則編譯失敗。
public interface A { /** default訪問修飾符修飾的方法 */ default void methodB1() { System.out.println("this is default method -- InterfaceA"); } /** static修飾符修飾的方法 */ public static void methodB2() { System.out.println("this is static method -- InterfaceA"); } } public interface B{ /** default訪問修飾符修飾的方法 */ default void methodB1() { System.out.println("this is default method -- InterfaceB"); } /** static修飾符修飾的方法 */ public static void methodB2() { System.out.println("this is static method -- InterfaceB"); } } public class Test implements A,B{ /** 由於A和B中default方法一樣,所以這里必須覆蓋 */ @Override public void methodB1() { System.out.println("this is Overriding methods"); } public static void main(String[] args) { /** 接口的default方法,通過接口的實現類的對象調用 */ Test test = new Test(); test.methodB1(); /** A接口的靜態方法,通過接口名調用 */ A.methodB2(); /** B接口的靜態方法,通過接口名調用 */ B.methodB2(); } }
運行結果:
參考: https://blog.csdn.net/aitangyong/article/details/54134385