以前我們知道,接口中的方法必須時抽象方法,而從 java8 開始接口中也可以有方法的實現了,叫做默認方法。
一 、默認方法(default修飾)
在 java8 中,因為存在函數式接口,一個接口中只能存在一個普通方法,但是可以寫多個默認方法,來為實現類提供方法實現。
1 public interface MyInterface { 2 3 /** 4 * 默認方法 5 * @return 6 */ 7 default String getName () { 8 return "張三"; 9 } 10 11 default String getAge () { 12 return "13"; 13 } 14 15 /** 16 * 普通方法 17 * @return 18 */ 19 String getHome (); 20 }
既然接口中可以寫方法的實現,那么就會出現與父類之間進行沖突的問題。
1 public class MyClass { 2 3 public String getName () { 4 return "李四"; 5 } 6 }
上面的類中同樣存在一個方法 getName 如果有一個類即實現 MyInterface 的接口, 又繼承 MyClass 的類,那么這個類的 geName 方法到底使用接口中的還是父類中的呢?
1 public class My_JAVA8_Test extends MyClass implements MyInterface{ 2 3 public static void main(String[] args) { 4 My_JAVA8_Test test = new My_JAVA8_Test(); 5 System.out.println(test.getName()); 6 } 7 8 9 @Override 10 public String getHome() { 11 return null; 12 } 13 14 }
答案是“李四”,因為,這里有一個類優先的原則:
若一個接口中定義了一個默認方法,而另一個父類中又定義了一個同名方法時,選擇父類中的方法。如果一個父類提供了具體的實現,那么接口中具有相同名稱和參數的默認方法會被忽略。
如果,此時,我們再定義一個接口,里面也有一個方法叫做getName,而一個類去同時實現這兩個接口。那么這個類的 getName 方法到底會執行哪一個呢?
1 public interface MyFun { 2 3 default String getName () { 4 return "王五"; 5 } 6 }
1 public class My_JAVA8_Test implements MyInterface, MyFun{ 2 3 public static void main(String[] args) { 4 My_JAVA8_Test test = new My_JAVA8_Test(); 5 System.out.println(test.getName()); 6 } 7 8 9 @Override 10 public String getHome() { 11 return null; 12 } 13 14 /** 15 * 此時,類會讓我們自己去重寫,也可以自己選擇使用上面2個接口中的方法 16 */ 17 @Override 18 public String getName() { 19 return MyFun.super.getName(); 20 } 21 22 }
此時,類會讓我們自己去重寫,也可以自己選擇使用上面2個接口中的方法
若一個接口中定義了一個默認方法,而另外一個接口中又定義了一個同名方法時,接口沖突。不管是否是默認方法,那么必須覆蓋該方法來解決沖突。
二、靜態方法
在 java8 中的接口中不僅增加了默認方法,還增加了靜態方法。使用方式接口名.方法名。
1 public interface MyFun { 2 3 default String getName () { 4 return "王五"; 5 } 6 7 static void test () { 8 System.out.println("測試接口中靜態方法!"); 9 } 10 }
1 public static void main(String[] args) { 2 MyFun.test(); 3 4 }
