一. 接口默認方法
1. 定義
接口不只是一個只能聲明方法的地方,還可以在聲明方法的時候,給方法一個默認的實現,而不需要實現類去實現其方法。默認方法用default關鍵字修飾,它默認就是public權限的。
2. 特點
(1)所有的實現類都會自動繼承接口中定義的默認方法;
(2)接口中的默認方法可以被實現類重寫;
(3)在被調用時,實現類重寫后的方法優先於默認方法;
(4)和1.8之前一樣,在接口中仍然不允許定義普通的實現方法,接口任然會保持除這些新特性外的所有原有特性.
3. 舉例

1 package com.test.a; 2 3 public interface Base { 4 public default void f() {// only public,default,abstract 5 System.out.println("hello world1"); 6 } 7 8 default void f2() { 9 System.out.println("hello world2"); 10 } 11 12 public void f3();;// 必須不能有方法體 13 14 public static void f4() {// 必須要有方法體,即使方法體中沒有具體的實現邏輯 15 System.out.println("hello world4"); 16 } 17 18 }

1 package com.test.a; 2 3 public class Sub implements Base { 4 5 @Override 6 public void f3() { 7 System.out.println("hello world3"); 8 9 } 10 11 public void f2() {//只可以時public,因為父類是public,子類不可以縮小父類的訪問權限 12 System.out.println("hahahh"); 13 } 14 15 }

1 package com.test.a; 2 3 public class Test { 4 5 public static void main(String args[]) { 6 Sub sub = new Sub(); 7 sub.f(); 8 sub.f2(); 9 sub.f3(); 10 Base.f4();// f4只可以Base來調用 11 12 } 13 }

1 hello world1 2 hahahh 3 hello world3 4 hello world4
4. 為什么引入default方法?
(1)以前的接口中只要定義了方法,都需要在實現類中進行實現。即使是個空的實現,也必須寫出來;但是在新特性中,添加了默認方法,就無需在實現類中再次實現了,除非想要再次實現,直接重寫就可以了;
(2)為接口添加新的默認方法,是不會破壞原有接口的實現;
(3)不需要修改接口的實現類,就可以為接口添加新的方法實現;
(4)對於已經發布的版本,是無法在給接口添加新方法的同時而不影響已有的實現,因此引入了default。目的是為了解決接口的修改與已有的實現不兼容的問題。
5. 易錯點
(1)如果一個類實現兩個或兩個以上接口,並且多個接口中包含統一默認方法,此時,編譯器將報錯。這種情況,我們必須讓子類Override該方法,否則無法編譯通過。

1 public interface Base { 2 public default void f() {// only public,default,abstract 3 System.out.println("hello world1"); 4 } 5 6 default void f2() { 7 System.out.println("hello world2"); 8 } 9 10 public void f3();;// 必須不能有方法體 11 12 public static void f4() {// 必須要有方法體,即使方法體中沒有具體的實現邏輯 13 System.out.println("hello world4"); 14 } 15 16 } 17 18 package com.test.a; 19 20 public interface Base2 { 21 default void f2() { 22 System.out.println("Base2 hello world2"); 23 } 24 25 }
上面就會提示要么重寫Base的f2方法,要么重寫Base2的f2方法;
(2)如果是一個接口繼承了另外一個接口,2個接口中也包含相同的默認方法,那么繼承接口的版本具有更高的優先級。比如A繼承了B接口,那么優先使用A接口里面的default方法;
(3)通過使用super,可以顯式的引用被繼承接口的默認實現,語法如下:InterfaceName.super.methodName()。

1 package com.test.a; 2 3 public interface Base { 4 public default void f() {// only public,default,abstract 5 System.out.println("hello world1"); 6 } 7 8 default void f2() { 9 System.out.println("hello world2"); 10 } 11 12 public void f3();;// 必須不能有方法體 13 14 public static void f4() {// 必須要有方法體,即使方法體中沒有具體的實現邏輯 15 System.out.println("hello world4"); 16 } 17 18 } 19 20 package com.test.a; 21 22 public class Sub implements Base { 23 24 @Override 25 public void f3() { 26 System.out.println("hello world3"); 27 28 } 29 30 public void f2() { 31 Base.super.f2(); 32 } 33 34 }

1 hello world1 2 hello world2 3 hello world3 4 hello world4
二. 靜態方法
1. 定義
和普通的靜態方法定義一樣
2. 特點
(1)只能是靜態方法所屬的類來調用(即使是子類等等都不行)
(2)必須有方法體,即使方法體中沒有具體實現;區別於上面的普通方法必須不能有方法體;
(3)實現接口的類或者子接口不會繼承接口中的靜態方法。static不能和default同時使用。在java8中很多接口中都增加了靜態方法
3. 用途
(1)因為是靜態方法,它是不能被實現類重寫的(否則編譯異常:This static method cannot hide the instance method from Object),因此,它可以用來提供防止實現類不良重寫的保障;
(2)常常可以作為工具型的方法,比如:空值檢查,集合類排序等等;
(3)比如可以將java.util.collections類改成接口(eg:Collection) 中的靜態方法,進行調用;