jdk8jdk9-接口的變化以及好處

在jdk8之前,interface之中可以定義變量和方法,變量必須是public、static、final的,方法必須是public、abstract的。由於這些修飾符都是默認的以下寫法等價

public interface JDK8BeforeInterface { 
public static final int field1 = 0; 

int field2 = 0; 

public abstract void method1(int a) throws Exception; 

void method2(int a) throws Exception; 
}

JDK8及以後,允許我們在接口中定義static方法和default方法。

public interface JDK8Interface { 

// static修飾符定義靜態方法 
static void staticMethod() { 
System.out.println("接口中的靜態方法"); 
} 

// default修飾符定義默認方法 
default void defaultMethod() { 
System.out.println("接口中的默認方法"); 
} 
}

public class JDK8InterfaceImpl implements JDK8Interface { 
//實現接口後,因爲默認方法不是抽象方法,所以可以不重寫,但是如果開發需要,也可以重寫 
}

public class Main { 
public static void main(String[] args) { 
// static方法必須通過接口類調用 
JDK8Interface.staticMethod(); 

//default方法必須通過實現類的對象調用 
new JDK8InterfaceImpl().defaultMethod(); 
} 
}

當然如果接口中的默認方法不能滿足某個實現類需要,那麼實現類可以覆蓋默認方法。

public class AnotherJDK8InterfaceImpl implements JDK8Interface { 

// 簽名跟接口default方法一致,但是不能再加default修飾符 
@Override 
public void defaultMethod() { 
System.out.println("接口實現類覆蓋了接口中的default"); 
} 
}

由於java支持一個實現類可以實現多個接口,如果多個接口中存在同樣的static和default方法會怎麼樣呢?如果有兩個接口中的靜態方法一模一樣,並且一個實現類同時實現了這兩個接口,此時並不會產生錯誤,因爲jdk8只能通過接口類調用接口中的靜態方法,所以對編譯器來說是可以區分的。但是如果兩個接口中定義了一模一樣的默認方法,並且一個實現類同時實現了這兩個接口,那麼必須在實現類中重寫默認方法,否則編譯失敗
也就是說繼承兩個接口如果有相同的默認方法類,就需要去重寫默認方法。

好處

這樣實現的好處:可以對於解決某些情況下,接口中的某些方法在子類之中的實現是一樣的,這樣就能減少重複代碼,完成代碼的複用;

Java9 的接口私有方法

抽象方法和接口的比較

接口方法默認修飾符是public。在java9以後可以用private定義私有方法,私有方法必須包含方法體。

通過以上對比抽象類的使用場景被削減,那麼什麼時候還需要使用抽象類
1、需要構造方法。
2、獨立運行。
3、定義final方法防止子類篡改

在使用接口過程中需要注意如下幾個問題:

1、Interface的所有方法訪問權限自動被聲明爲public。在java9以後可以定義私有方法,但是必須有方法體不能是抽象方法。

2、接口中可以定義“成員變量”,或者說是不可變的常量,因爲接口中的“成員變量”會自動變爲爲public static final。可以通過類命名直接訪問:ImplementClass.name。

3、不能使用new操作符實例化一個接口,但可以聲明一個接口變量,該變量必須引用(refer to)一個實現該接口的類的對象。可以使用 instanceof 檢查一個對象是否實現了某個特定的接口。例如:if(anObject instanceof Comparable){}。

4、在實現多接口的時候一定要避免方法名的重複,尤其是default方法。

5、接口裏的方法不能用final修飾

在使用抽象類時需要注意幾點:

1、抽象類不能被實例化,實例化的工作應該交由它的子類來完成,它只需要有一個引用即可。

2、抽象方法必須由子類來進行重寫。

3、只要包含一個抽象方法的抽象類,該類必須要定義成抽象類。

4、抽象類中可以包含具體的方法,當然也可以不包含抽象方法。

5、子類中的抽象方法不能與父類的抽象方法同名。

6、abstract不能與final並列修飾同一個類。

7、abstract 不能與private、static、final或native並列修飾同一個方法。

參數 抽象類 接口
默認的方法實現 它可以有默認的方法實現 jdk1.8之前沒有,現在可以使用default關鍵字創在interface中創建一個default方法,該方法包含了具體的實現代碼,一個接口中可以有多個default方法
實現 子類使用extends關鍵字來繼承抽象類。如果子類不是抽象類的話,它需要提供抽象類中所有抽象的方法的實現。 子類使用關鍵字implements來實現接口。它需要提供接口中所有聲明的非default方法的實現
構造器 抽象類可以有構造器 接口沒有構造器
實例化 不能 不能
訪問修飾符 抽象方法可以有public、protected和default這些修飾符 接口方法默認修飾符是public。在java9以後可以用private定義私有方法,私有方法必須包含方法體。 私有方法體只能自己接口內使用
main方法 抽象方法可以有main方法並且我們可以運行它 接口沒有main方法,因此我們不能運行它。
繼承 單一繼承 多繼承
訪問速度 它比接口速度要快 接口是稍微有點慢的,因爲它需要時間去尋找在類中實現的方法
添加新方法 如果你往抽象類中添加新的方法,你可以給它提供默認的實現。因此你不需要改變你現在的代碼。 jdk1.8以後可以添加了,也就是說有一些在接口設計上的頑疾現在有了完美解決的方法
public interface SimpleInterface {
     public void doSomeWork();
      //A default method in the interface created using "default" keyword
      //使用default關鍵字創在interface中直接創建一個default方法,該方法包含了具體的實現代碼
      default public void doSomeOtherWork(){
          getStu();
        System.out.println("DoSomeOtherWork implementation in the interface");
      }
      static void getStatic() {
          System.out.println("static method");
        }
      default public void doSomeOtherWork2(){
          getStu();
          //私有靜態方法用於爲接口中的默認方法服務
          getStatic1();
            System.out.println("DoSomeOtherWork2 implementation in the interface");
          }
      //java9中可以創建私有方法了
      private void getStu() {
          System.out.println( "private method!");
        }
    //java9中可以創建私有靜態方法了
      private static void getStatic1() {
          System.out.println("private static method");
        }
}

class SimpleInterfaceImpl implements SimpleInterface{
 @Override
 public void doSomeWork() {
   System.out.println("Do Some Work implementation in the class");
 }
 @Override
 public void doSomeOtherWork() {
   System.out.println("Do doSomeOtherWork implementation in the class");
 }
 /*
  * Not required to override to provide an implementation 
  * for doSomeOtherWork.
  * 在SimpleInterfaceImpl裏,不需要再去實現接口中定義的doSomeOtherWork方法
  */

 public static void main(String[] args) {
     SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
   simpObj.doSomeWork();
   simpObj.doSomeOtherWork();
   simpObj.doSomeOtherWork2();
   SimpleInterface.getStatic();
 }
}
···


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章