接口中的變量默認類型是public static final,也是就是說是
公有靜態常量
。 而方法默認是public abstract,公有抽象方法
,但是事實真的是這樣嗎?
一.新特性
Java 1.8對接口有兩個方面的增強:接口中可以添加使用default或者static修飾的方法
-
增加default方法
:又叫做接口擴展方法
,即在不破壞java現有實現架構的情況下能往接口裏增加新方法, default關鍵字可以給接口添加一個非抽象的方法實現,子類可以直接調用!如果想對接口增加一個新方法,那麼需要對實現該接口的所有類進行修改,如果接口實的現類很多,就會帶來很大的工作量,而且還很容易破壞以前的代碼,帶來一些問題。如果把新的方法定義爲default方法,就可以避免對其他實現類的修改。
儘管如此,Default 方法不適合過多使用
-
增加static方法
: 接口中用static修飾的方法也可以有方法體,和類的靜態方法一樣,可以通過 接口名.方法名 進行接口中 static方法的調用。
二.defalut方法
- 實現類會繼承接口中的default方法
如果接口A中有default方法:
public interface A {
public default void a(){
System.out.println("這是AAA");
}
}
B類實現接口A:
public class B implements A{
}
那麼B類將會繼承接口A中的a方法:
public class Main {
public static void main(String[] args) {
B b = new B();
b.a();
}
}
執行結果:
- 如果一個類同時實現接口A和B,接口A和B中有相同的default方法,這時,該類必須重寫接口中的default方法
爲什麼要重寫呢?是因爲,類在繼承接口中的default方法時,不知道應該繼承哪一個接口中的default方法。
接口A:
public interface A {
public default void a(){
System.out.println("這是A");
}
}
接口B:
public interface B {
public default void a(){
System.out.println("這是B");
}
}
Test類:
com.demo.test.Test inherits unrelated defaults for a() from types com.demo.test.A and com.demo.test.B
可以看出,接口的實現類可以直接調用接口中用default修飾的方法,並且不需要實現該方法(也可以實現)
- 如果子類繼承父類,父類中有a方法,該子類同時實現的接口中也有a方法(被default修飾),那麼子類會繼承父類的a方法而不是繼承接口中的a方法
接口A:
public interface A {
public default void a(){
System.out.println("AAA");
}
}
類B:
public class B {
public void a(){
System.out.println("BBB");
}
}
子類C:
public class C extends B implements A{
public static void main(String[] args) {
C c = new C();
c.a();
}
}
執行結果:
說明子類繼承的b方法爲父類C中的b方法,不是接口中的default b(){}方法。
三.static方法
static關鍵字常用於修飾類的屬性和方法,同樣,在Java8,static也可以修飾接口的方法
接口A:
public interface A {
public static void a(){
System.out.println("AAA");
}
}
調用接口A的靜態方法:
public class B {
public static void main(String[] args) {
A.a();
}
}
執行結果:
可以看出,在接口中用static修飾的方法,可以直接用接口名.方法名(這裏A.a())調用,並且實現類不能實現接口中static修飾的方法。