前言
今天學習集合源碼時,在Iterable接口中發現default關鍵字。
是什么?
default是在java8中引入的關鍵字,也可稱為Virtual extension methods——虛擬擴展方法。
是指,在接口內部包含了一些默認的方法實現(也就是接口中可以包含方法體,這打破了Java之前版本對接口的語法限制),從而使得接口在進行擴展的時候,不會破壞與接口相關的實現類代碼。
為什么要?
之前的接口是個雙刃劍,好處是面向抽象而不是面向具體編程,缺陷是,當需要修改接口時候,需要修改全部實現該接口的類。
默認方法使得開發者可以在不破壞二進制兼容性的前提下,往現存接口中添加新的方法,即不強制那些實現了該接口的類也同時實現這個新加的方法。
二進制兼容性:所謂“二進制兼容性”指的就是在升級(也可能是 bug fix)庫文件的時候,不必重新編譯使用這個庫的可執行文件或使用這個庫的其他庫文件,程序的功能不被破壞。
怎么用?
1、繼承接口,實現接口
public interface Interface1{ default void helloWorld() { System.out.println("Interface1"); } }
public class MyImplement implements Interface1{ public static void main(String[] args) { MyImplement myImplement = new MyImplement(); //直接調用helloWorld()方法 myImplement.helloWorld(); } }
2、同時實現兩個有同名默認方法的接口
public interface Interface2{ default void helloWorld() { System.out.println("Interface2"); } }
/** * 實現接口Interface1,Interface2 */ public class MyImplement implements Interface1,Interface2{ public static void main(String[] args) { MyImplement myImplement = new MyImplement(); //直接調用helloWorld()方法 myImplement.helloWorld(); } }
報錯,不知道該調用哪個方法。解決辦法:在實現類中重寫該方法。
3、類優於接口
public class MyImplement2 extends MyImplement implements Interface2{ public static void main(String[] args) { MyImplement2 myImplement2 = new MyImplement2(); myImplement2.helloWorld(); } }
會調用父類方法。
注:1、jdk8.0中允許接口中使用靜態方法。
2、盡管默認方法有這么多好處,但在實際開發中應該謹慎使用:在復雜的繼承體系中,默認方法可能引起歧義和編譯錯誤。