JDK8中接口的變化
那麼多學技術的都可以成功,憑什麼我不行
在JDK8之前,接口之中可以定義變量和方法。
變量必須(默認)是public、static、final的,方法必須(默認)是public、abstract的。
由於這些修飾符都是默認的以下寫法等價:
public interface JDK8BeforeInterface {
public static final int field1 = 0;
int field2 = 0;
public abstract void method1(int a) throws Exception;
void method2(int a) throws Exception;
}
在JDK8之後,接口中可以有默認的方法實現,和靜態方法。
public interface JDK8Interface {
// static修飾符定義靜態方法
static void staticMethod() {
System.out.println("接口中的靜態方法");
}
// default修飾符定義默認方法
default void defaultMethod() {
System.out.println("接口中的默認方法");
}
}
public class JDK8InterfaceImpl implements JDK8Interface {
//實現接口後,因爲默認方法不是抽象方法,所以可以不重寫,但是如果開發需要,也可以重寫
}
public class Main {
public static void main(String[] args) {
// static方法必須通過接口類調用
JDK8Interface.staticMethod();
//default方法必須通過實現類的對象調用
new JDK8InterfaceImpl().defaultMethod();
}
}
當然如果接口中的默認方法不能滿足某個實現類需要,那麼實現類可以覆蓋默認方法。
public class AnotherJDK8InterfaceImpl implements JDK8Interface {
// 簽名跟接口default方法一致,但是不能再加default修飾符
@Override
public void defaultMethod() {
System.out.println("接口實現類覆蓋了接口中的default");
}
}
由於java支持一個實現類可以實現多個接口,如果多個接口中存在同樣的static和default方法會怎麼樣呢?
如果有兩個接口中的靜態方法一模一樣,並且一個實現類同時實現了這兩個接口,此時並不會產生錯誤,因爲JDK8只能通過接口類調用接口中的靜態方法,所以對編譯器來說是可以區分的。
但是如果兩個接口中定義了一模一樣的默認方法,並且一個實現類同時實現了這兩個接口,那麼會產生默認方法衝突,編譯器會提示接口衝突,讓我們自行解決,那麼必須在實現類中重寫默認方法,否則編譯失敗。
當一個接口實現另一個接口時,子接口與父接口存在相同的默認方法時,將採用父類接口的默認方法。
當一個類既繼承父類又實現接口時,如果父類中的方法與接口中的默認方法衝突,將會執行父類中的方法,而不是接口中的方法,這種情況被稱爲類優先選擇,方便兼容JDK8之前的版本。