JavaRush /Java Blog /Random-TW /Java 中的介面

Java 中的介面

在 Random-TW 群組發布
你好!今天我們來談談Java中的一個重要概念—介面。這個詞你可能很熟悉。例如,大多數電腦程式和遊戲都有介面。從廣義上講,介面是一種連接互動兩方的「遙控器」。日常生活中的介面的一個簡單範例是電視遙控器。它連接兩個物體,一個人和一台電視,並執行不同的任務:調高或調低音量、改變頻道、打開或關閉電視。一側(人)需要存取介面(按下遙控器按鈕),另一側才能執行操作。例如,讓電視切換到下一個頻道。在這種情況下,使用者不需要知道電視的設備以及其內部如何實現改變頻道的過程。為什麼Java中需要介面 - 1使用者可以存取的只是介面。主要任務是獲得期望的結果。這與程式設計和 Java 有什麼關係?直接:) 建立介面與建立常規類別非常相似,只是class我們指定的單字不是interface。讓我們來看看最簡單的 Java 接口,並弄清楚它是如何工作的以及它的用途:
public interface Swimmable  {

     public void swim();
}
我們創造了一個可以游泳的Swimmable介面。這就像我們的遙控器,有一個“按鈕”:方法 是“游泳”。我們該如何使用這個「遙控器」呢?為此,該方法,即 我們需要實現遙控器上的按鈕。要使用接口,它的方法必須由我們程式的某些類別實現。讓我們設計一個類,其物件符合「可以游泳」的描述。例如,鴨子類就適合: swim()Duck
public class Duck implements Swimmable {

    public void swim() {
        System.out.println("Duck, swim!");
    }

    public static void main(String[] args) {

        Duck duck = new Duck();
        duck.swim();
    }
}
我們在這裡看到什麼?使用關鍵字將類別Duck與介面關聯起來。如果你還記得的話,我們在繼承中使用了類似的機制來連接兩個類,只是有「extends」這個詞。為了清楚起見, “ ”可以按字面意思翻譯:“公共類別實作介面。” 這意味著與介面關聯的類別必須實現其所有方法。請注意:在我們的類別中,就像在介面中一樣,有一個方法,裡面有某種邏輯。這是強制性要求。如果我們只寫了“ ”,並沒有在類別中創建方法,編譯器會給我們一個錯誤: Duck is not abstract and does not override abstract method Swim() in Swimmable 為什麼會發生這種情況呢?如果我們用電視的例子來解釋這個錯誤,就會發現我們給一個人一個帶有「更改頻道」按鈕的遙控器,而電視不知道如何更改頻道。此時,無論按多少次按鈕,都不會起作用。遙控器本身不會改變頻道:它只是向電視發出信號,電視內部執行了一個複雜的改變頻道的過程。我們的鴨子也是如此:它必須能夠游泳,以便可以使用介面存取它。如果她不知道如何做到這一點,介面將無法連接兩個方面——人和程式。人無法使用方法使程式內的物件浮動。現在您已經更清楚地了解了介面的用途。介面描述了實作該介面的類別必須具有的行為。「行為」是方法的集合。如果我們想建立多個信使,最簡單的方法是建立一個介面。任何使者應該能夠做什麼?以簡化的形式接收和發送訊息。 Swimmableimplementspublic class Duck implements SwimmableDuckSwimmableDuckSwimmableswim()public class Duck implements Swimmableswim()DuckSwimmableSwimmableswim()DuckMessenger
public interface Messenger{

     public void sendMessage();

     public void getMessage();
}
現在我們可以透過實作這個介面來簡單地創建我們的信使類別。編譯器本身會「強迫」我們在類別中實作它們。電報:
public class Telegram implements Messenger {

    public void sendMessage() {

        System.out.println("Sending a message to Telegram!");
    }

     public void getMessage() {
         System.out.println("Reading the message in Telegram!");
     }
}
微信:
public class WhatsApp implements Messenger {

    public void sendMessage() {

        System.out.println("Sending a WhatsApp message!");
    }

     public void getMessage() {
         System.out.println("Reading a WhatsApp message!");
     }
}
維伯:
public class Viber implements Messenger {

    public void sendMessage() {

        System.out.println("Sending a message to Viber!");
    }

     public void getMessage() {
         System.out.println("Reading a message in Viber!");
     }
}
這有什麼好處?其中最重要的是松耦合。想像一下,我們正在設計一個程序,我們將在其中收集客戶資料。該類別Client必須有一個欄位指示客戶端使用哪個信使。如果沒有接口,它看起來會很奇怪:
public class Client {

    private WhatsApp whatsApp;
    private Telegram telegram;
    private Viber viber;
}
我們創建了三個字段,但一個客戶很容易只有一個信使。我們只是不知道是哪一個。為了不與客戶失去溝通,你必須將所有可能的選項「推」到課堂上。事實證明,其中一兩個總是存在null,程式運行根本不需要它們。相反,最好使用我們的介面:
public class Client {

    private Messenger messenger;
}
這是「鬆散耦合」的一個例子!我們沒有在類別中指定特定的信使類Client,而是簡單地提到客戶端有一個信使。哪一個將在計劃過程中確定。但為什麼我們需要介面呢?為什麼要將它們加入語言?這個問題問得好,也正確!使用普通繼承也可以達到相同的結果,對嗎?該類別Messenger是父類, 、和Viber是繼承人。確實,這樣做是可能的。但有一個問題。如您所知,Java 中不存在多重繼承。但接口有多種實作。一個類別可以實作任意多個介面。想像一下,我們有一個類,它有一個字段- 一個安裝在智慧型手機上的應用程式。 TelegramWhatsAppSmartphoneApplication
public class Smartphone {

    private Application application;
}
當然,應用程式和信使很相似,但它們仍然是不同的東西。Messenger 可以是行動和桌面端,而 Application 是行動應用程式。因此,如果我們使用繼承,我們將無法Telegram向類別新增物件Smartphone。畢竟,一個類別Telegram不能繼承ApplicationMessenger!我們已經成功地從 繼承它Messenger,並以這種形式將其添加到類別中Client。但是一個類別Telegram可以輕鬆實現這兩個介面!因此,在類別中Client我們可以將物件實作為TelegramMessenger在類別中Smartphone實作為Application。其操作方法如下:
public class Telegram implements Application, Messenger {

    //...methods
}

public class Client {

    private Messenger messenger;

    public Client() {
        this.messenger = new Telegram();
    }
}


public class Smartphone {

    private Application application;

    public Smartphone() {
        this.application = new Telegram();
    }
}
Telegram現在我們可以隨意 使用這個類別了。他將在某個地方扮演...的角色Application,在某個地方扮演...的角色Messenger。您可能已經注意到介面中的方法總是“空”,也就是說,它們沒有實現。原因很簡單:介面描述行為,而不是實現它。「實作該介面的類別的所有物件都Swimmable必須能夠浮動」:這就是介面告訴我們的全部內容。Fish魚、鴨或馬到底如何游泳是類、Duck和的問題Horse,而不是接口的問題。就像改變頻道是電視的任務。遙控器只是給您一個按鈕即可執行此操作。然而,Java8 有一個有趣的補充——預設方法。例如,您的介面有 10 個方法。其中 9 個在不同類別中實作不同,但其中 1 個在所有類別中實作相同。以前,在Java8發布之前,介面內的方法根本沒有實作:編譯器立即拋出錯誤。現在你可以這樣做:
public interface Swimmable {

   public default void swim() {
       System.out.println("Swim!");
   }

   public void eat();

   public void run();
}
使用關鍵字default,我們在介面中建立了一個具有預設實作的方法。我們需要在所有要實作 的類別中實作另外兩個方法eat()和。無需使用該方法執行此操作:所有類別中的實作都是相同的。順便說一句,您在過去的任務中不止一次遇到過接口,儘管您自己沒有註意到:)這是一個明顯的例子: 您使用接口並且!更準確地說,是透過它們的實現 - 、和其他。同一張圖顯示了一個類別同時實作多個介面的範例。例如,它實作了介面and (雙面佇列)。您也熟悉該接口,或者更確切地說,熟悉它的實作。順便說一句,在這張圖中你可以看到一個特性:介面可以互相繼承。此介面繼承自,並且繼承自queue 。如果您想顯示介面之間的連接,但一個介面是另一個介面的擴充版本,則這是必要的。讓我們看一個帶有介面的範例- 隊列。我們還沒有瀏覽過這些系列,但它們非常簡單,排列得就像商店裡的常規隊伍一樣。您只能將元素新增至佇列的末尾,並且只能從開頭將它們刪除。在某個階段,開發人員需要佇列的擴充版本,以便可以從兩側新增和接收元素。這就是創建介面的方式——雙向隊列。它包含常規隊列的所有方法,因為它是雙向隊列的“父級”,但添加了新方法。 run()Swimmableswim()為什麼我們需要 Java 中的介面 - 2ListSetArrayListLinkedListHashSetLinkedListListDequeMapHashMapSortedMapMapDequeQueueQueueQueueDeque
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION