Java 中的介面還可以這樣用,你知道嗎?

語言: CN / TW / HK

Java​ 程式設計師都知道要面向介面程式設計,那 Java​ 中的介面除了定義介面方法之外還能怎麼用你知道嗎?今天阿粉就來帶大家看一下 Java 中的介面還可以有哪些用法。

基本特性

我們先看一下介面的基本特性

  • 介面的定義需要使用關鍵字interface;
  • 介面定義的所有方法預設都是public abstract;
  • 當一個具體的class​ 去實現一個interface​時,需要使用implements 關鍵字;
  • 介面之間是可以多繼承,而類是隻能單繼承的;

如下所示,我們定義一個介面;

package com.example.demo.inter;

import java.io.Serializable;
import java.util.RandomAccess;


public interface ITest extends Serializable, RandomAccess {

  public abstract String sayHello();
  String sayHello2();

}

預設方法

在 JDK 8​ 之前介面是不支援預設方法的,在 JDK 8​ 之後介面支援預設方法,預設方法採用關鍵詞 default 宣告。

public interface ITest extends Serializable, RandomAccess {

  public abstract String sayHello();
  String sayHello2();
  
  
  default String sayHello3() {
    return "hello3";
  }

}

預設方法跟抽象方法不一樣,介面中定義的抽象方法,當介面被其他類實現的時候都需要全部實現,但是預設方法是不需要被實現就可以直接使用的,類似於直接呼叫父類的方法一樣,所以在很多時候,我們已經繼承了一個類,還想有一個能用但是不想每個子類都實現的方法的時候,就可以考慮增加一個介面的預設方法來使用,簡單來說就是實現類可以不覆寫 default 方法。

default方法存在的目的是,在我們已經完善的專案中,如果我們直接給一個介面增加一個方法,在沒有預設方法的時候就需要給所有的實現類都實現對應的方法,但是這個方法又不一定是每個實現類都需要的,所以這個時候預設方法就很好的解決了這個問題,我們只需要增加一個預設方法,然後在需要使用的實現類中進行實現或者使用就可以了,其他的實現類不需要改動任何的程式碼。

標記

介面還有一個很常見的功能那就是標記功能,這麼說可能你沒有印象,但是到提到序列化介面 java.io.Serializable;​ 你肯定知道,我們經常在對應的 POJO 中都會實現這個序列化介面,而這個序列化的介面如果看過原始碼的小夥伴肯定知道里面是沒有內容的。

同樣的功能除了序列化的介面,類似的空介面還有很多,比如 java.util.RandomAccess​ 也是空介面,之前阿粉也寫過關於 RandomAccess​ 這個介面的用途,感興趣的可以再去看看。RandomAccess 明明是個空介面,能有什麼用呢?

通過原始碼我們可以知道 RandomAccess 是用來標識子類是否實現了該介面,如果實現了則走實現了的邏輯,沒有實現就走沒有實現的邏輯,所以我們在日常開發中也可以利用這個特性,當我們有不同的子類需要根據情況進行不同的實現邏輯的時候就可以採用定義一個空介面來標記一下,方便後面的處理。

靜態方法

跟預設方法一樣,JDK 8 還支援在介面中增加靜態方法,雖然說在介面中定義靜態方法的做法不常見,但是當需要使用的時候也是可以支援的,避免在建立一個單獨的工具類,跟在類中定義的靜態方法一樣,我們可以直接通過介面名稱引用靜態方法,當然靜態變數也是可以的,使用方法一樣。

public interface ITest extends Serializable, RandomAccess {

  public abstract String sayHello();
  String sayHello2();
  default String sayHello3() {
    System.out.println(sayHello4());
    return "hello3";
  }
  public static String sayHello4() {
    return "hello4";
  }
}

私有方法

大家有沒有注意到,上面不管是預設方法還是靜態方法其實都是 public​ 公開的,可以讓實現類或者其他類直接使用,那有沒有可能在介面中定義一個私有方法呢?在 JDK 9​ 之前是不可以的,JDK 9 卻支援了,如下所示

private void privateMethod() {
    System.out.println("private私有方法被呼叫");
  }

  private static void privateStaticMethod() {
    System.out.println("private私有靜態方法被呼叫");
  }

從官方的文件中我們可以找到下面的描述,在 JDK 9 中介面支援私有方法,主要用於不同的非抽象方法中共享程式碼。

我們可以看到在 JDK 9 這樣寫是可以的

但是在 JDK8​ 就不行了,是無法編譯通過的,會提示不允許使用 private 修飾符。

總結

今天阿粉給大家總結了一個介面的使用方法,後面在日常的開發中我們不單單只是在介面中定義抽象方法,也可以根據需求增加預設方法或者私有方法,以及在需要用到標記的時候也可以通過定義一個空介面來實現,怎麼樣是不是很棒,感覺動起來吧。