如您所知,Java 中的一切都由物件組成,物件具有狀態(欄位)和行為(由方法定義)。類別的行為可以將其綁定到其他類別。行為可以有不同的特徵,有時將其移到類別之外會更方便,尤其是在與外界互動時。就像電視的遙控器在“盒子”本身之外一樣。遙控器是用戶與電視功能互動的介面。例如,您可以想像一個實作抽象飛機或直升機的類別。這兩類物體(例如大多數鳥類)都可以飛行,而且它們的飛行方式都不同。也許值得將此功能轉移到單獨的實體中,並且所有潛在的“傳單”都將從該實體繼承?如果您已經熟悉抽象類,則可以建立抽象類別 Flyable 並從中「繼承」Copter 和 Plane 類別。但是,如果有多個這樣的屬性怎麼辦?例如,飛機和直升機可以飛行,也可以在地面上行駛。即使我們建立了 Ride 類,我們也不能再將 Copter 和 Plane 指派給它。畢竟,每個Java類別只有一個父類別。
使用Java語言中的介面部分解決了這個問題。Java 中的介面定義了一些沒有特定實作的功能,然後由使用這些介面的類別來實作。並且一個類別可以實作多個介面。事實上,透過在 Java 中實作一個接口,我們聲明我們的類別可以做某事,我們報告它的行為。我們已經在類別中進行了行為的具體實現。所以。飛機和直升機的起飛方式不同:飛機需要跑道,直升機通常垂直起飛。這些細節最好在課堂上實施。

Java 中的介面
在Java語言中定義介面需要使用interface關鍵字。例如:interface Voice {
void talk();
}
上面的介面稱為Voice。Java 中的介面可以定義常數和方法,它們可能有也可能沒有實作。通常,介面方法沒有實現,就像本例一樣。介面中沒有實作的方法就像是抽象類別的抽象方法。介面方法通常沒有存取修飾符。然而,預設存取實際上是公共的,因為介面的目的是定義類別實現的功能。因此,所有功能都應該開放以供實施。若要實作接口,請在聲明類別時使用Implements關鍵字。此外,如果介麵包含沒有實作的方法,則該方法必須在實作類別中實作。
public class Duck implements Voice {
@Override
public void voice() {
System.out.println("Quack");
}
}
介面程式碼範例
讓我們舉一個更完整的例子。每一種(好吧,幾乎每一種)動物都有發出聲音的能力。讓我們為此案例建立一個 Java 介面Voice 。它有一個talk()方法,但沒有實作。public interface Voice {
void talk();
}
現在,所有支援Voice介面的類別都必須具有talk()方法的實作。讓我們建立兩個類別 - Cat和Dog並指示它們實作Voice介面。在這種情況下,如果你不在其中實作一個類,程式將無法運行。實作方法非常簡單。當呼叫Cat類物件的talk()方法時,螢幕上會顯示相當於喵叫的文本,對於Dog類,則為吠叫。我們還將為類別添加 getter、setter 和建構子。
public class Cat implements Voice {
String name;
String breed;
int year;
public Cat(String name, String breed, int year) {
this.name = name;
this.breed = breed;
this.year = year;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
@Override
public void talk() {
System.out.println("meow...");
}
}
public class Dog implements Voice {
String name;
String color;
int year;
public Dog(String name, String color, int year) {
this.name = name;
this.color = color;
this.year = year;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
@Override
public void talk() {
System.out.println("WOF WOF");
}
}
事實上,我們的類別和方法實作非常相似。讓我們建立另一個具有語音支援的類別Parrot。只有talk()方法的工作方式有所不同:使用者將在控制台中輸入一個字串,parrot 將使用 talk ()方法「重複」它。
import java.util.Scanner;
public class Parrot implements Voice {
String name;
String color;
int year;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
@Override
public void talk() {
Scanner scanner = new Scanner(System.in);
System.out.println("WHat should I repeat after you?...");
String s = scanner.nextLine();
System.out.println(s);
}
}
現在我們建立一個測試類,看看如果依序 呼叫Cat、Dog和Parrot類別物件的talk()方法,程式會產生什麼結果。
public class InterfaceDemo {
public static void main(String[] args) {
Cat cat = new Cat ("Mewie", "Siam" ,2021);
cat.talk();
Dog dog = new Dog("Snoopy", "White and black", 2020);
dog.talk();
Parrot parrot = new Parrot();
parrot.talk();
}
}
輸出如下。綠色文字是使用者在控制台中列印的一個文字。
喵...WOF WOF 我應該在你後面重複什麼?...我是非常健談和聰明的鳥 我是非常健談和聰明的鳥
預設方法
在 JDK 8 版本之前,在用 Java 實作介面時,我們必須在類別中實作其所有方法。同時,Java介面本身可以只包含方法定義,而沒有具體的實作。JDK 8 新增了新功能-預設方法。現在,Java 介面不僅可以有方法定義,還可以有預設實作。如果類別實作介面但未實作方法,則使用它們。例如,我們將Voice介面中的talk()方法變更為預設方法。我們還將編寫一個新的支援語音的Duck類,該類沒有talk方法的實作。public interface Voice {
default void talk() {
System.out.println("I can talk...");
}
}
public class Duck implements Voice {
public void moveForward() {
System.out.println(" Quack, I am moving forward...");
}
public void TurnRight(){
System.out.println("I am turning right...");
}
public void TurnLeft(){
System.out.println("I am turning left...");
}
public void Stop() {
System.out.println("Quack. I am relaxing on the surface of the water...");
}
public void fly(){
System.out.println("I am flying!!!");
}
}
現在讓我們稍微改變一下我們的測試類別。
public class InterfaceDemo {
public static void main(String[] args) {
Cat cat = new Cat ("Mewie", "Siam" ,2021);
cat.talk();
Dog dog = new Dog("Snoopy", "White and black", 2020);
dog.talk();
Duck duck = new Duck();
duck.talk();
}
}
輸出在這裡:
喵…WOF WOF 我會說話…
看?在Dog和Cat類別的物件中,呼叫重寫的方法talk() ,但在Duck類別的物件中,呼叫介面中的預設方法。因此,default方法只是一個沒有修飾符的方法,並用default關鍵字標記。我們不必在實作介面的類別中實作預設方法,但我們可以重寫它。
靜態方法
由於 JDK 8 靜態方法在 Java 介面中可用 - 它們類似於類別方法:interface Voice {
void talk();
static void check(){
System.out.println("checked...");
}
}
要引用介面的靜態方法,就像類別的情況一樣,寫下介面的名稱和方法:
public static void main(String[] args) {
Voice.check();
}
介面的多種實現
如果我們需要在Java類別中應用多個接口,那麼它們都在implements後面用逗號列出:public class Duck implements Swimmable, Flyable, Voice {
public void moveForward() {
System.out.println(" Quack, I am moving forward...");
}
public void TurnRight(){
System.out.println("I am turning right...");
}
public void TurnLeft(){
System.out.println("I am turning left...");
}
public void Stop() {
System.out.println("Quack. I am relaxing on the surface of the water...");
}
public void fly(){
System.out.println("I am flying!!!");
}
}
GO TO FULL VERSION