納尼,接口中可以定義實例方法了?!
納尼,接口中還可以定義靜態方法了?!
沒錯,在Java8中新增了很多新的特性,其中就包括可以在接口中添加方法和變量。
首先我們來看下代碼
1 public interface SourceInterface 2 { 3 int a = 5; 4 int b = 10; 5 6 public static int add() 7 { 8 return a + b; 9 } 10 11 public static void reset() 12 { 13 // do sth 14 } 15 16 public default int f1() 17 { 18 return a; 19 } 20 21 public default void f2() 22 { 23 // do sth 24 } 25 } 26 27 class learnCode 28 { 29 public void userInterface() 30 { 31 int xx = SourceLearning.add(); 32 SourceLearning.reset(); 33 SourceLearning instance = new SourceLearning() 34 { 35 @Override 36 public void f2() 37 { 38 // do sth 、 39 } 40 }; 41 instance.f1(); 42 instance.f2(); 43 //int y=instance.add(); 注意這句會編譯錯誤 44 } 45 }
代碼中,我們可以發現以下幾點不同:
1、在接口中,可以直接添加靜態方法。
該靜態方法作為接口(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )的類方法,可以直接使用。不需要依托某個實現類。
2、在接口中,可以直接添加非抽象的實例方法。
在實例方法的申明中,需要增加default關鍵字修飾,因此這種方法也稱為默認方法。他是接口自帶的方法。接口被實現后,實例可以直接使用這些默認方法,同時如果對默認方法需要重寫時,可以直接重寫即可。
這兩點新特性相對於java8之前的版本來說,可以說有質的改變。
引申:
可以增加方法的接口,開始變的更像抽象類。Java類在實現了多個擁有默認方法的接口后,從側面展現的像是實現了多重繼承的影子。
注意:如果兩個接口的默認方法出現重復申明,則需要在實現方法中重寫該方法,否則jvm在執行時,無法確定究竟應該使用哪個接口的同名方法。這應該可以算是本次新引入特性的一個弊端,如果是指定使用的是某個接口中的默認方法時,可以采用
1 @Override 2 public void f2() 3 { 4 SourceLearning.super.f2(); 5 }
的形式
那么,java為什么要引入默認方法呢?如果需要往接口中添加方法,直接使用抽象類即可,為什么要破壞已有的約定呢?
我認為主要原因如下:
在面向接口的編程過程中,發現原有的接口中,都需要添加一個相同的方法,那么現在有兩種方案:
1)接口換抽象類,(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )抽象類中添加該方法
2)接口中添加該抽象方法,在每一個接口的實現類中,均添加相同的實現方法。
無論選擇哪種方法,都需要對已有的代碼做出非常大的改動。可是如果使用默認方法,使對接的接口默認就擁有某些功能的實現,則很好的解決了假設的問題。