Java中的介面定義了一個參照型別來建立抽象概念。 介面由類實現,它是用來提供概念的實現。
在Java 8之前,一個介面只能包含抽象方法。 Java 8允許介面具有實現的靜態和預設方法。
介面通過抽象概念定義不相關類之間的關係。例如,可以建立一個Person
類來表示一個人,也可以建立一個Dog
類來表示一隻狗。
人和狗都可以走路。 這裡的走路是一個抽象的概念。 狗可以走路,人也是走路。這裡可以建立一個名為Walkable
的介面來表示走路這個概念。然後在Person
類和Dog
類中各自實現Walkable
概念(如:實現怎麼走路)。 Person
類實現了Walkable
介面以人的方式走路(如:用兩條腿走路)。 Dog
類可以實現Walkable
介面以狗的方式走路(如:用四條腿走路)。
下面將使用一個例子來說明為什麼需要介面。
假設Person
類有一個walk()
方法。
在相同的包下建立一個介面檔案 - Walkable.java 並使用以下程式碼 -
public interface Walkable {
void walk(); // 介面中只有一個方法
}
在相同的包下建立一個主類 -Main.java 並使用以下程式碼 -
class Person implements Walkable {
public Person() {
}
public void walk() {
System.out.println("人走路:使用兩條腿足路.");
}
}
class Dog implements Walkable {
public Dog() {
}
public void walk() {
System.out.println("狗走路:使用四條腿足路.");
}
}
public class Main {
public static void main(String[] args) {
Walkable[] w = new Walkable[2];
w[0] = new Person();
w[1] = new Dog();
w[0].walk();
w[1].walk();
// 或者
// Person p = new Person();
// p.walk();
}
}
上面的程式碼輸出結果如下 -
人走路:使用兩條腿足路.
狗走路:使用四條腿足路.
類可以在其宣告中使用關鍵字implements
實現一個或多個介面。通過實現一個介面,類保證它將為介面中宣告的所有方法提供一個實現,或者類將自己宣告為抽象。
如果一個類實現了Walkable
介面,它必須提供walk()
方法的具體實現。
像類一樣,介面定義了一個新的參照型別。當定義一個新的介面(例如,Walkable
)時,定義一個新的參考介面型別。
以下宣告有效:
Walkable w; // w is a reference variable of type Walkable
但是不能建立介面型別的物件,因為介面是定義抽象概念。 以下程式碼無效,編譯會出錯:
new Walkable(); // A compile-time error
只能為類型別建立物件,但是可以使用一個介面型別變數來參照那些類實現該介面的任何物件。
如:Person
和Dog
類都實現了Walkable
介面,所以Walkable
型別的參照變數可以參照這兩個類的物件。如下程式碼是沒有問題的:
Walkable w1 = new Person(); // OK
Walkable w2 = new Dog(); // OK
可以使用它的參照型別變數存取介面的任何成員。 由於Walkable
介面只有一個成員,也就是walk()
方法,所以這裡可以編寫如下程式碼:
// Let the person walk
w1.walk();
// Let the dog walk
w2.walk();
當呼叫w1
的walk()
方法時,它呼叫Person
物件的walk()
方法,因為w1
指的是Person
物件。當呼叫w2
的walk()
方法時,它呼叫Dog
物件的walk()
方法,因為w2
指的是Dog
物件。
當使用介面型別的參照變數呼叫方法時,它將呼叫它所參照的物件的方法。
下面的程式碼建立了一個方法來使用介面引數型別。
public class Main{
public static void main(String[] args) {
Walkable[] w = new Walkable[2];
w[0] = new Person();
w[1] = new Dog();
Walkables.letThemWalk(w);
}
}
class Walkables {
public static void letThemWalk(Walkable[] list) {
for (Walkable w : list) {
w.walk();
}
}
}
宣告介面的一般語法是 -
<modifiers> interface <interface-name> {
Constant-Declaration
Method-Declaration
Nested-Type-Declaration
}
介面宣告以修飾符列表開頭,也可以為空(不寫)。像類一樣,一個介面可以有一個公共或包級別的範圍。
關鍵字public
用於指示介面具有公共範圍。缺少範圍(不使用)修飾符表示介面具有包級別作用域。 具有包級別作用域的介面只能在其包的成員內參照。
關鍵字interface
用於宣告介面,後面是介面的名稱。
介面的名稱必須是有效的Java識別符號。介面主體跟在其名稱後面並放在大括號內。介面的主體可以為空。 以下是最簡單的介面宣告:
package com.yiibai;
interface Updatable {
// The interface body is empty
}
像類一樣,一個介面有一個簡單的名稱和一個完全限定名。關鍵字interface
後面的識別符號是其簡單名稱。介面的完全限定名稱通過使用其包名稱和用點分隔的簡單名稱組成。
在上面的範例中,Updatable
是簡單的名稱,com.yiibai.Updatable
是完全限定名稱。使用介面的簡單和完全限定名的規則與類的規則相同。
下面的程式碼宣告一個名為ReadOnly
的介面。 它有一個公共(public
)範圍。
package com.yiibai;
public interface ReadOnly {
// The interface body is empty
}
介面宣告總是抽象的,無論是否明確宣告它為抽象。
標記介面是沒有成員的介面。標記介面用來標記類具有特殊含義。
interface Shape {
}
class Circle implements Shape{
}
Shape c = new Circle();
if (c instanceof Shape) {
System.out.println("Using a Shape object");
}
Java API有許多標記介面。如:java.lang.Cloneable
,java.io.Serializable
和java.rmi.Remote
都是標記介面。
僅具有一個抽象方法的介面被稱為功能介面。
多型性是指物件具有多種形式的能力。多型性是物件提供其不同檢視的能力。使用介面使得我們可以建立一個多型物件。