介面是類的抽象,沒有實現細節。例如,java.lang.Comparable 是 Java 中的標準介面。你無法例項化介面。介面不是類,但它以相同的方式編寫。第一個區別是,你不用 class 關鍵字,而是用 interface 關鍵字來定義它。然後,你不能在這裡定義欄位和方法
- 欄位始終是常量:它始終是公共的、靜態的和最終的,即使你沒有提到它。
- 方法必須是公共的和抽象的,但不需要寫
public 和 abstract 關鍵字。
- 建構函式是被禁止的。
介面代表一個契約
|
程式碼清單 4.14:SimpleInterface.java
public interface SimpleInterface {
public static final int CONSTANT1 = 1;
int method1(String parameter);
}
|
你可以看到 method1() 方法是抽象的(未實現)。要使用介面,你必須定義一個實現它的類,使用 implements 關鍵字
|
程式碼清單 4.15:ClassWithInterface.java
public class ClassWithInterface implements SimpleInterface {
public int method1(String parameter) {
return 0;
}
}
|
一個類可以實現多個介面,用逗號分隔。Java 介面的行為與 Objective-C 協議的概念非常相似。建議將介面命名為 <動詞>able,表示此介面將在類上啟用的操作型別。但是,不建議在介面名稱前面加上 I,如 C++ 中那樣。這沒有用。你的 IDE 會為你提供幫助。
如果你有來自不同類且沒有共同超類的物件,你無法在這些類中呼叫相同的方法,即使這兩個類實現了具有相同簽名的方法。
|
程式碼清單 4.16:OneClass.java
public class OneClass {
public int method1(String parameter) {
return 1;
}
}
|
|
程式碼清單 4.17:AnotherClass.java
public class AnotherClass {
public int method1(String parameter) {
return 2;
}
}
|
|
程式碼部分 4.16:無法呼叫。
public static void main(String[] args) {
doAction(new OneClass());
doAction(new AnotherClass());
}
public void doAction(Object anObject) {
anObject.method1("Hello!");
}
|
解決方法是編寫一個定義應該在兩個類中實現的方法的介面,如 程式碼清單 4.14 中的 SimpleInterface,然後這兩個類都可以實現介面,如 程式碼清單 4.15 中那樣。
|
程式碼部分 4.17:介面使用。
public static void main(String[] args) {
doAction(new ClassWithInterface());
doAction(new AnotherClassWithInterface());
}
public void doAction(SimpleInterface anObject) {
anObject.method1("Hello!");
}
|
你也可以使用一個共同的超類來實現這一點,但一個類只能從一個超類繼承,而它可以實現多個介面。
Java 不支援完全正交多重繼承(即 Java 不允許你從兩個類建立子類)。C++ 中的多重繼承有複雜的規則來消除從多個超類繼承的欄位和方法以及多次繼承的型別的歧義。透過將介面與實現分離,介面在複雜性和歧義性較小的情況下提供了多重繼承的大部分優勢。沒有多重繼承的代價是一些程式碼冗餘;由於介面只定義類的簽名,而不能包含任何實現,所以每個繼承介面的類都必須提供定義方法的實現,不像純粹的多重繼承那樣,實現也是繼承的。這樣做的主要好處是,所有 Java 物件都可以有一個共同的祖先(一個名為 Object 的類)。
在覆蓋介面中定義的方法時,需要遵循一些規則
- 不應該在實現方法上宣告受檢異常,除了介面方法宣告的異常或介面方法宣告的異常的子類。
- 在實現方法時,應該保持介面方法的簽名和相同的返回型別或子型別。
- 實現介面的類需要定義介面的所有方法,除非該類是抽象類。
在 BlueJ 上執行此示例。
介面可以擴充套件多個介面,類似於類可以擴充套件另一個類的方式,使用 extends 關鍵字
|
程式碼清單 4.18:InterfaceA.java
public interface InterfaceA {
public void methodA();
}
|
|
程式碼清單 4.19:InterfaceB.java
public interface InterfaceB {
public void methodB();
}
|
|
程式碼清單 4.20:InterfaceAB.java
public interface InterfaceAB extends InterfaceA, InterfaceB {
public void otherMethod();
}
|
這樣,實現InterfaceAB介面的類必須實現methodA()、methodB()和otherMethod()方法。
|
程式碼清單 4.21:ClassAB.java
public class ClassAB implements InterfaceAB {
public void methodA() {
System.out.println("A");
}
public void methodB() {
System.out.println("B");
}
public void otherMethod() {
System.out.println("foo");
}
public static void main(String[] args) {
ClassAB classAb = new ClassAB();
classAb.methodA();
classAb.methodB();
classAb.otherMethod();
}
}
|
這樣做,ClassAB物件可以被強制轉換為InterfaceA、InterfaceB和InterfaceAB。