Java介面:介面的定義和介面的實現,定義介面,實現介面

2020-07-16 10:05:16
介面類似於類,但介面的成員沒有執行體,它只是方法、屬性、事件和索引符的組合而已。介面不能被範例化,介面沒有構造方法,沒有欄位。在應用程式中,介面就是一種規範,它封裝了可以被多個類繼承的公共部分。

定義介面

介面繼承和實現繼承的規則不同,一個類只有一個直接父類別,但可以實現多個介面。Java 介面本身沒有任何實現,只描述 public 行為,因此 Java 介面比 Java 抽象類更抽象化。Java 介面的方法只能是抽象的和公開的,Java 介面不能有構造方法,Java 介面可以有 public、static 和 final 屬性。

介面把方法的特徵和方法的實現分隔開來,這種分隔體現在介面常常代表一個角色,它包裝與該角色相關的操作和屬性,而實現這個介面的類便是扮演這個角色的演員。一個角色由不同的演員來演,而不同的演員之間除了扮演一個共同的角色之外,並不要求其他的共同之處。

介面對於其宣告、變數和方法都做了許多限制,這些限制作為介面的特徵歸納如下:
  • 具有 public 存取控制符的介面,允許任何類使用;沒有指定 public 的介面,其存取將局限於所屬的包。
  • 方法的宣告不需要其他修飾符,在介面中宣告的方法,將隱式地宣告為公有的(public)和抽象的(abstract)。
  • 在 Java 介面中宣告的變數其實都是常數,介面中的變數宣告,將隱式地宣告為 public、static 和 final,即常數,所以介面中定義的變數必須初始化。
  • 介面沒有構造方法,不能被範例化。例如:
public interface A {
    publicA(){…}    // 編譯出錯,介面不允許定義構造方法
}
  • 一個介面不能夠實現另一個介面,但它可以繼承多個其他介面。子介面可以對父介面的方法和常數進行重寫。例如:
public interface StudentInterface extends PeopleInterface {
    // 介面 StudentInterface 繼承 PeopleInterface
    int age = 25;    // 常數age重寫父介面中的age常數
    void getInfo();    // 方法getInfo()重寫父介面中的getInfo()方法
}
Java 介面的定義方式與類基本相同,不過介面定義使用的關鍵字是 interface,介面定義由介面宣告和介面體兩部分組成。語法格式如下:
[public] interface interface_name [extends interface1_name[, interface2_name,…]] {
    // 介面體,其中可以包含定義常數和宣告方法
    [public] [static] [final] type constant_name = value;    // 定義常數
    [public] [abstract] returnType method_name(parameter_list);    // 宣告方法
}
其中,public 表示介面的修飾符,當沒有修飾符時,則使用預設的修飾符,此時該介面的存取許可權僅侷限於所屬的包;interfaCe_name 表示介面的名稱,可以是任何有效的識別符號;extends 表示介面的繼承關係;interface1_name 表示要繼承的介面名稱;constant_name 表示變數名稱,一般是 static 和 final 型的;returnType 表示方法的返回值型別;parameter_list 表示參數列,在介面中的方法是沒有方法體的。

提示:如果介面本身被定義為 public,則所有的方法和常數都是 public 型的。

例如,定義一個介面 MyInterface,並在該介面中宣告常數和方法,如下:
public interface MyInterface {    // 介面myInterface
    String name;    // 不合法,變數name必須初始化
    int age = 20;    // 合法,等同於 public static final int age=20;
    void getInfo();    // 方法宣告,等同於 public abstract void getInfo();
}

實現介面

介面被定義後,一個或者多個類都可以實現該介面,這需要在實現介面的類的定義中包含 implements 子句,然後實現由介面定義的方法。實現介面的一般形式如下:
<public> class <class_name> [extends superclass_name] [implements interface[, interface…]] {
    //主體
}

如果一個類實現多個介面,這些介面需要使用逗號分隔。如果一個類實現兩個宣告了同樣方法的介面,那麼相同的方法將被其中任一個介面使用。實現介面的方法必須宣告為 public,而且實現方法的型別必須嚴格與介面定義中指定的型別相匹配。

例 1

在程式的開發中,需要完成兩個數的求和運算和比較運算功能的類非常多。那麼可以定義一個介面來將類似功能組織在一起。下面建立一個範例,具體介紹介面的實現方式。

1)建立一個名稱為 IMath 的介面,程式碼如下:
public interface IMath {
    public int sum();    // 完成兩個數的相加
    public int maxNum(int a,int b);    // 獲取較大的數
}
2)定義一個 MathClass 類並實現 IMath 介面,MathClass 類實現程式碼如下:
public class MathClass implements IMath {
    private int num1;    // 第 1 個運算元
    private int num2;    // 第 2 個運算元
    public MathClass(int num1,int num2) {
        // 構造方法
        this.num1 = num1;
        this.num2 = num2;
    }
    // 實現介面中的求和方法
    public int sum() {
        return num1 + num2;
    }
    // 實現介面中的獲取較大數的方法
    public int maxNum(int a,int b) {
        if(a >= b) {
            return a;
        } else {
            return b;
        }
    }
}
在實現類中,所有的方法都使用了 public 存取修飾符宣告。無論何時實現一個由介面定義的方法,它都必須實現為 public,因為介面中的所有成員都顯式宣告為 public。

3)最後建立測試類 NumTest,範例化介面的實現類 MathClass,呼叫該類中的方法並輸出結果。該類內容如下:
public class NumTest {
    public static void main(String[] args) {
        // 建立實現類的物件
        MathClass calc = new MathClass(100, 300);
        System.out.println("100 和 300 相加結果是:" + calc.sum());
        System.out.println("100 比較 300,哪個大:" + calc.maxNum(100, 300));
    }
}
程式執行結果如下所示。
100 和 300 相加結果是:400
100 比較 300,哪個大:300
在該程式中,首先定義了一個 IMath 的介面,在該介面中只宣告了兩個未實現的方法,這兩個方法需要在介面的實現類中實現。在實現類 MathClass 中定義了兩個私有的屬性,並賦予兩個屬性初始值,同時建立了該類的構造方法。因為該類實現了 MathClass 介面,因此必須實現介面中的方法。在最後的測試類中,需要建立實現類物件,然後通過實現類物件呼叫實現類中的方法。