介紹
default是在java8中引入的關鍵字,也可稱為Virtual
extension methods——虛擬擴展方法。是指,在接口內部包含了一些默認的方法實現(也就是接口中可以包含方法體,這打破了Java之前版本對接口的語法限制),從而使得接口在進行擴展的時候,不會破壞與接口相關的實現類代碼。
為什么需要這個特性
首先,之前的接口是個雙刃劍,好處是面向抽象而不是面向具體編程,缺陷是,當需要修改接口時候,需要修改全部實現該接口的類,目前的java8之前的集合框架沒有foreach方法,通常能想到的解決辦法是在JDK里給相關的接口添加新的方法及實現。然而,對於已經發布的版本,是沒法在給接口添加新方法的同時不影響已有的實現。所以引進的默認方法。他們的目的是為了解決接口的修改與現有的實現不兼容的問題。
簡單的說就是,在想在接口中直接定義新方法但是,這樣的話,就得在所有實現類中都重寫新方法,所以引進了default關鍵字,方便所有實現類都可繼承default的新方法。
使用default關鍵字
特性1:調用接口實現繼承的default方法
interface A{
default void print(){
System.out.println("I am A");
}
}
class X implements A{
}
public class StudyDefault {
public static void main(String[] args) {
X x = new X();
x.print();
}
}
運行結果
這里可以看出,這個接口的default的方法是可以繼承的,正常來說,接口方法只能是抽象方法,且不能有方法體,必須要被重寫,但這里不一樣,這就是Java8的新特性之一的體現。
特性2:同時實現兩個接口
這時會發現,X類出現錯誤,因為實現了A和B兩個接口,它們都有default修飾的同名的print方法,那么這個方法必須被重寫了。看下面代碼
interface A{
default void print(){
System.out.println("I am A");
}
}
interface B{
default void print(){
System.out.println("I am B");
}
}
class X implements A,B{
@Override
public void print() {
System.out.println("I am X");
}
}
public class StudyDefault {
public static void main(String[] args) {
X x = new X();
x.print();
}
}
運行結果
繼承父類比繼承接口優先級更高
代碼1
interface A {
default void print() {
System.out.println("I am A");
}
}
interface B {
default void print() {
System.out.println("I am B");
}
}
class C{
public void print(){
System.out.println("I am C");
}
}
class X extends C implements A {
}
public class StudyDefault {
public static void main(String[] args) {
X x = new X();
x.print();
}
}
運行結果
代碼2
interface A {
default void print() {
System.out.println("I am A");
}
}
interface B {
default void print() {
System.out.println("I am B");
}
}
class X {
public void print() {
System.out.println("I am X");
}
}
public class StudyDefault extends X implements A{
public static void main(String[] args) {
StudyDefault studyDefault = new StudyDefault();
studyDefault.print();
}
}
運行結果
從上面兩個例子可以看出繼承的是父類的print方法,故父類優先級是高於接口的。
注意
參考代碼1
我若把
public
刪掉,那么下面的X類會報錯。
我覺得可以理解為C類的public修飾符一旦去掉,那么C類中的print方法也就變成了default屬性,那么X繼承C類且實現A接口就相當於變成了實現兩個用default修飾的相同方法的接口了,就是特性2中的實現兩個接口的情形。