JavaRush /Java Blog /Random-JA /Java のインターフェース

Java のインターフェース

Random-JA グループに公開済み
こんにちは!今日は Java の重要な概念であるインターフェイスについて話します。この言葉はおそらくあなたもよく知っているでしょう。たとえば、ほとんどのコンピュータ プログラムやゲームにはインターフェイスがあります。広い意味では、インターフェイスは、相互に対話する 2 者を接続する一種の「リモコン」です。日常生活におけるインターフェースの簡単な例としては、テレビのリモコンが挙げられます。人間とテレビという 2 つのオブジェクトを接続し、音量の上げ下げ、チャンネルの変更、テレビのオン/オフなどのさまざまなタスクを実行します。一方の側 (人) がアクションを実行するには、もう一方の側がインターフェイスにアクセスする (リモコンのボタンを押す) 必要があります。たとえば、テレビのチャンネルを次のチャンネルに切り替えます。この場合、ユーザーは TV のデバイスや、チャンネルを変更するプロセスがその内部でどのように実装されているかを知る必要はありません。Java にインターフェースが必要な理由 - 1ユーザーがアクセスできるのはインターフェイスのみです。主なタスクは、望ましい結果を取得することです。これはプログラミングや Java とどのような関係があるのでしょうか? 直接:) インターフェイスの作成は通常のクラスの作成と非常に似ていますが、単語の代わりに単語をclass指定しますinterface。最も単純な Java インターフェイスを見て、それがどのように機能し、何に必要なのかを理解してみましょう。
public interface Swimmable  {

     public void swim();
}
泳ぐことができるSwimmableインターフェース を作成しました。これは、「ボタン」が 1 つあるリモコンのようなものです。メソッドは 「スイム」です。この「リモコン」はどうやって使うのでしょうか?この目的のためのメソッド、すなわち リモコンのボタンを実装する必要があります。インターフェイスを使用するには、そのメソッドをプログラムの一部のクラスで実装する必要があります。「泳げる」という説明に当てはまるオブジェクトを持つクラスを考えてみましょう。たとえば、アヒルクラスが適しています。 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インターフェイスに関連付けられます。覚えていると思いますが、継承で 2 つのクラスを接続するために同様のメカニズムを使用しましたが、「 extends 」という単語があっただけでした。「」はわかりやすくするために直訳すると、「パブリック クラスがインターフェイスを実装する」になります。これは、インターフェイスに関連付けられたクラスがそのメソッドをすべて実装する必要があることを意味します。注意してください:このクラスには、インターフェイスと同様にメソッドがあり、その中にはある種のロジックがあります。これは必須の要件です。「 」を記述しただけで、 class にメソッドを作成しなかった場合、コンパイラは 次のエラーを表示します。テレビの例を使ってエラーを説明すると、チャンネルの変更方法を知らないテレビから「チャンネル変更」ボタンが付いたリモコンを人に渡していることがわかります。この時点では、ボタンを好きなだけ押しても何も動作しません。リモコン自体はチャンネルを変更しません。テレビに信号を与えるだけであり、その内部にはチャンネルを変更する複雑なプロセスが実装されています。私たちのアヒルも同様です。インターフェイスを使用してアクセスできるように、アヒルは泳ぐことができなければなりません。彼女がこれを行う方法を知らなければ、インターフェイスは人間とプログラムの 2 つの側面を結び付けることができません。プログラム内のオブジェクトをフロートさせるメソッドを使用することはできません。これで、インターフェースの目的がより明確に理解できました。インターフェイスは、そのインターフェイスを実装するクラスが持つ必要のある動作を記述します。「行動」はメソッドの集合体です。複数のメッセンジャーを作成したい場合、最も簡単な方法は、 インターフェース を作成することです。メッセンジャーは何をすればよいのでしょうか? 簡易形式でメッセージを送受信します。 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;
}
3 つのフィールドを作成しましたが、クライアントは簡単にメッセンジャーを 1 つだけ持つことができます。どちらなのかは分かりません。そして、クライアントとのコミュニケーションが取れないままにならないように、すべての可能なオプションをクラスに「プッシュ」する必要があります。nullそれらのうちの 1 つまたは 2 つは常にそこに存在し、プログラムが動作するためにはまったく必要ないことがわかります。代わりに、次のインターフェイスを使用することをお勧めします。
public class Client {

    private Messenger messenger;
}
これは「疎結合」の一例です。class で特定のメッセンジャー クラスを指定する代わりにClient、クライアントがメッセンジャーを持っていることを単に言及します。どちらになるかはプログラムの過程で決定されます。しかし、なぜこれにインターフェースが必要なのでしょうか? そもそもなぜそれらが言語に追加されたのでしょうか? 質問は良くて正しいです!通常の継承を使用しても同じ結果が得られますね。クラスはMessenger親クラスであり、 とViberTelegram継承WhatsApp者です。確かに、そうすることは可能です。しかし、落とし穴が 1 つあります。すでにご存知のとおり、Java には多重継承はありません。ただし、インターフェイスの実装は複数あります。クラスは好きなだけインターフェイスを実装できます。スマートフォンにインストールされたアプリケーションという Smartphoneフィールドを持つクラスがあると想像してください。Application
public class Smartphone {

    private Application application;
}
アプリケーションとメッセンジャーは、もちろん似ていますが、それでも別のものです。メッセンジャーはモバイルとデスクトップの両方に使用できますが、アプリケーションはモバイル アプリケーションです。Telegramしたがって、継承を使用すると、クラスにオブジェクトを追加できなくなりますSmartphone。結局のところ、クラスは!からTelegram継承することはできません。そして、それを から継承し、この形式でクラスに追加することができました。ただし、クラスは両方のインターフェイスを簡単に実装できます。したがって、クラスではオブジェクトをとして実装でき、クラスではとして実装できます。その方法は次のとおりです。 ApplicationMessengerMessengerClientTelegramClientTelegramMessengerSmartphoneApplication
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フローティング可能でなければなりません」: インターフェイスが私たちに伝えるのはこれだけです。魚、アヒル、馬がどのように正確に泳ぐかは、インターフェースではなくクラスFishDuckおよびクラスに関する問題です。Horseチャンネルを変えるのがテレビの仕事と同じです。リモコンには、それを実行するためのボタンが表示されるだけです。ただし、Java8 にはデフォルトのメソッドという興味深い追加機能があります。たとえば、インターフェイスには 10 個のメソッドがあります。そのうち 9 つは異なるクラスで異なる方法で実装されていますが、1 つはすべてで同じに実装されています。Java8 がリリースされる前は、インターフェース内のメソッドにはまったく実装がなく、コンパイラーはすぐにエラーをスローしていました。これで、次のようにできるようになります。
public interface Swimmable {

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

   public void eat();

   public void run();
}
キーワードを使用してdefault、デフォルトの実装を持つインターフェースにメソッドを作成しました。他の 2 つのメソッドとeat()を、run()を実装するすべてのクラスに自分自身で実装する必要がありますSwimmable。メソッドでこれを行う必要はありませんswim()。実装はすべてのクラスで同じになります。ところで、あなた自身は気づいていませんが、過去のタスクで何度かインターフェイスに遭遇しました:) ここに明らかな例があります: Java にインターフェースが必要な理由 - 2あなたはインターフェイスListSet!を操作しました。より正確には、その実装 - ArrayListLinkedListHashSetその他。同じ図は、1 つのクラスが複数のインターフェイスを同時に実装する場合の例を示しています。たとえば、LinkedListインターフェイスListDeque(両面キュー) を実装します。あなたはインターフェースMap、あるいはその実装についてもよく知っていますHashMap。ところで、この図では、インターフェイスを相互に継承できるという特徴が 1 つあります。インターフェイスSortedMapは から継承されMap、 およびDequequeue から継承されますQueue。これは、インターフェイス間の接続を表示したい場合に必要ですが、あるインターフェイスが別のインターフェイスの拡張バージョンです。Queueインターフェイスであるキューの例を見てみましょう。まだコレクションを見ていませんがQueue、非常にシンプルで、店頭の通常のラインのように配置されています。要素はキューの末尾にのみ追加でき、要素を削除できるのは先頭からのみです。ある段階で、開発者は要素を両側から追加および受信できるようにキューの拡張バージョンを必要としました。Dequeこれが、双方向キューというインターフェイスの作成方法です。これは双方向キューの「親」であるため、通常のキューのすべてのメソッドが含まれていますが、新しいメソッドが追加されています。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION