介面 (Java)
此條目包含過多行話或專業術語,可能需要簡化或提出進一步解釋。 (2013年1月19日) |
介面(英語:Interface),在Java程式語言中是一個抽象型別(Abstract Type),它被用來要求類別(Class)必須實作指定的方法,使不同類別的物件可以利用相同的介面進行溝通。介面通常以interface
來宣告,它僅能包含方法簽名(Method Signature)以及常數宣告(變數宣告包含了 static
及 final
),一個介面不會包含方法的實作(僅有定義)。在Java 8之後,被放寬為允許定義預設方法——在介面具體實現方法,和類別靜態方法。
介面無法被實例化,但是可以被實作。一個實作介面的類別,必須實作介面內所描述的所有方法,否則就必須宣告為抽象類別(Abstract Class)。另外,在Java中,介面型別可用來宣告一個變數,他們可以成為一個空指標,或是被綁定在一個以此介面實現的物件。
其中一個使用介面的優勢是,可以利用他們模擬多重繼承,類別在JAVA中不允許多重繼承,所有在JAVA中的類別必須而且僅能有一個父類別,而java.lang.Object
(JAVA型別系統中最頂層的型別)是唯一一個例外。
JAVA的類別可以被實作許多個介面,然而一個介面則無法實作其他的介面。
概觀
[編輯]介面被用來統一類別的共通行為,當不同的類別需要進行資訊共用時,是不需要特別去建立類別間的關係。舉例來說,一個人(Human)及一隻鸚鵡(Parrot)都會吹口哨(whistle),然而Human
及Parrot
不應該為Whistler
的子類別,最好的做法是令他們為Animal
的子類別,而他們可以使用Whistler
的介面進行溝通。
還有一種介面的使用方法,則是當一個物件有實現特定介面時,我們使用它是不需要知道它的類別,例如,一個事物因為口哨的噪音影響到其他人,對於其他人而言,就不需要知道噪音來源是來自人還是鸚鵡,因為他們可以確定,一個會吹口哨的事物正在吹口哨。舉一個更實際的例子,排序演算法可能會期待物件的型別是可以被Comparable
的,於是它只需要知道物件的型別可以被以某種方式進行排序即可,這與物件的類別無關。whistler.whistle()
將會呼叫物件的實現方法whistle
,而不需要知道物件是以哪個類別來實現Whistler
。
例如:
interface Bounceable {
void setBounce(); // 注意分號
// 介面的方法(method)是公開(public)、抽象(abstract)、永遠不會是最尾端的型別(final)
// 把它們想成只是個模型,所以沒有任何方法有被實現
//以下语法在Java 8之后的版本是可行的,之前则编译错误
default void defaultMethod(){
System.out.println("defaultMethod");
setBounce(); //可以调用同接口的实例方法
}
}
使用方法
[編輯]介面的宣告
[編輯]下列的語法為介面的宣告方式:
[存取修飾] interface 介面名稱 [extends 其他的介面] { 常數宣告 抽象方法宣告 }
介面的主體包含着抽象方法,但所有方法在介面內(定義上)都是抽象(Abstract)方法,所以abstract
的關鍵字在介面內則不被需要。由於介面代表着一個對外行為的集合,所以任何方法在介面內都是public
(公開的)。
所以,一個簡單的介面可以這麼寫
public interface Predator {
boolean chasePrey(Prey p);
void eatPrey(Prey p);
}
介面內的成員皆為靜態(static)、final及公開(public),反之,他們可以成為任何類別或介面的型別[1]
實現一個介面的語法,可以使用這個公式:
... implements 介面名稱[, 其他介面, 其他的..., ...] ...
類別可以用來實現介面,舉例來說
public class Lion implements Predator {
public boolean chasePrey(Prey p) {
// programming to chase prey p (specifically for a lion)
}
public void eatPrey (Prey p) {
// programming to eat prey p (specifically for a lion)
}
}
如果一個類別實現了一個介面,而沒有實現介面的所有方法,則它必須被標注為abstract
(抽象類別)。一個抽象類別的子類別必須實現它未完成的方法,假如該項子類別仍不會實現介面的所有方法,那麼該項子類別依然需要被標注為abstract
。
類別可以同時實現多項介面
public class Frog implements Predator, Prey { ... }
介面通常被使用在Java程式語言,用來做回呼函數使用[2] 。Java並不允許方法作為參數傳遞使用,因此,其中一個解決辦法則是可以定義一個介面,把這個介面當成方法的參數,以此來使用該項物件的方法簽名。
子介面
[編輯]介面可以被延伸為數個不同的介面,可以使用上述所描述的方法,舉例來說:
public interface VenomousPredator extends Predator, Venomous {
//介面主體
}
以上的程式片段是合法定義的子介面,與類別不同的是,介面允許多重繼承,而Predator
及 Venomous
可能定義或是繼承相同的方法,比如說kill(Prey prey)
,當一個類別實現VenomousPredator
的時候,它將同時實現這兩種方法。
範例
[編輯]有些泛用的Java介面可供參考:
Comparable
擁有一個方法compareTo
,用以描述兩個物件是否相等,或是其中一個物件大於另外一個物件。泛型允許已經實現的類別,其物件可以用來互相比較。Serializable
是一個標記介面(marker interface),沒有任何方法或是成員,僅有一個空的主體,它被用來表示一個類別可以被序列化。它的Javadoc描述了他是如何運作,而且不需要被強制編程。
另見
[編輯]參考文獻
[編輯]- ^ The Java Language Specification. [2013-01-18]. (原始內容存檔於2012-02-29).
- ^ Java World. [2013-01-18]. (原始內容存檔於2008-09-16).