JavaRush /Java-Blog /Random-DE /Schnittstellen in Java

Schnittstellen in Java

Veröffentlicht in der Gruppe Random-DE
Hallo! Heute sprechen wir über ein wichtiges Konzept in Java – Schnittstellen. Das Wort kommt Ihnen wahrscheinlich bekannt vor. Beispielsweise verfügen die meisten Computerprogramme und Spiele über Schnittstellen. Im weitesten Sinne ist eine Schnittstelle eine Art „Fernsteuerung“, die zwei miteinander interagierende Parteien verbindet. Ein einfaches Beispiel für eine Schnittstelle aus dem Alltag ist eine TV-Fernbedienung. Es verbindet zwei Objekte, eine Person und einen Fernseher, und führt verschiedene Aufgaben aus: Lautstärke erhöhen oder verringern, Kanäle wechseln, Fernseher ein- oder ausschalten. Eine Seite (die Person) muss auf die Schnittstelle zugreifen (die Fernbedienungstaste drücken), damit die andere Seite die Aktion ausführen kann. Zum Beispiel, damit der Fernseher den Kanal auf den nächsten umschaltet. In diesem Fall muss der Benutzer das Gerät des Fernsehgeräts nicht kennen und wissen, wie der Prozess des Kanalwechsels darin implementiert wird. Warum brauchen wir Schnittstellen in Java - 1Der Benutzer hat lediglich Zugriff auf die Schnittstelle . Die Hauptaufgabe besteht darin, das gewünschte Ergebnis zu erzielen. Was hat das mit Programmierung und Java zu tun? Direkt :) Das Erstellen einer Schnittstelle ist dem Erstellen einer regulären Klasse sehr ähnlich, aber anstelle des Wortes classgeben wir das Wort an interface. Schauen wir uns die einfachste Java-Schnittstelle an und finden heraus, wie sie funktioniert und wofür sie benötigt wird:
public interface Swimmable  {

     public void swim();
}
Wir haben eine Schnittstelle geschaffen Swimmable, die schwimmen kann . Das ist so etwas wie unsere Fernbedienung, die einen „Knopf“ hat: Die Methode swim() ist „Schwimmen“. Wie können wir diese „ Fernbedienung “ nutzen? Zu diesem Zweck ist die Methode, d.h. Taste auf unserer Fernbedienung muss implementiert werden. Um eine Schnittstelle nutzen zu können, müssen ihre Methoden von einigen Klassen unseres Programms implementiert werden. Lassen Sie uns eine Klasse entwickeln, deren Objekte auf die Beschreibung „kann schwimmen“ passen. Geeignet ist beispielsweise die Entenklasse Duck:
public class Duck implements Swimmable {

    public void swim() {
        System.out.println(„Ente, schwimm!“);
    }

    public static void main(String[] args) {

        Duck duck = new Duck();
        duck.swim();
    }
}
Was sehen wir hier? Eine Klasse wird über das Schlüsselwort Duckmit einer Schnittstelle verknüpft . Wenn Sie sich erinnern, haben wir einen ähnlichen Mechanismus verwendet, um zwei Klassen bei der Vererbung zu verbinden, nur dass es das Wort „ extends “ gab. „ “ kann der Klarheit halber wörtlich übersetzt werden: „Eine öffentliche Klasse implementiert die Schnittstelle .“ Das bedeutet, dass eine einer Schnittstelle zugeordnete Klasse alle ihre Methoden implementieren muss. Bitte beachten Sie: In unserer Klasse gibt es genau wie in der Schnittstelle eine Methode und darin eine Art Logik. Dies ist eine zwingende Voraussetzung. Wenn wir nur „ “ schreiben und keine Methode in der Klasse erstellen würden , würde uns der Compiler eine Fehlermeldung geben: Duck ist nicht abstrakt und überschreibt die abstrakte Methode swim() in Swimmable nicht. Warum passiert das? Wenn wir den Fehler am Beispiel eines Fernsehers erklären, stellt sich heraus, dass wir einer Person eine Fernbedienung mit einer „Kanalwechsel“-Taste von einem Fernseher geben, der nicht weiß, wie man den Sender wechselt. Drücken Sie an dieser Stelle die Taste so oft Sie möchten, es funktioniert nichts. Die Fernbedienung selbst wechselt nicht den Kanal: Sie gibt lediglich ein Signal an den Fernseher, in dem ein komplexer Prozess des Kanalwechsels durchgeführt wird. So ist es auch bei unserer Ente: Sie muss schwimmen können, damit über die Schnittstelle darauf zugegriffen werden kann . Wenn sie nicht weiß, wie das geht, wird die Schnittstelle die beiden Seiten – die Person und das Programm – nicht verbinden. Eine Person wird nicht in der Lage sein, eine Methode zu verwenden , um ein Objekt innerhalb eines Programms schweben zu lassen. Jetzt haben Sie klarer gesehen, wozu Schnittstellen dienen. Eine Schnittstelle beschreibt das Verhalten, das Klassen haben müssen, die diese Schnittstelle implementieren. „Verhalten“ ist eine Sammlung von Methoden. Wenn wir mehrere Messenger erstellen möchten, ist dies am einfachsten, indem wir eine Schnittstelle erstellen . Was sollte ein Messenger können? In vereinfachter Form können Sie Nachrichten empfangen und senden. Swimmableimplementspublic class Duck implements SwimmableDuckSwimmableDuckSwimmableswim()public class Duck implements Swimmableswim()DuckSwimmableSwimmableswim()DuckMessenger
public interface Messenger{

     public void sendMessage();

     public void getMessage();
}
Und jetzt können wir unsere Messenger-Klassen einfach erstellen, indem wir diese Schnittstelle implementieren. Der Compiler selbst „zwingt“ uns, sie innerhalb von Klassen zu implementieren. Telegramm:
public class Telegram implements Messenger {

    public void sendMessage() {

        System.out.println(„Eine Nachricht an Telegram senden!“);
    }

     public void getMessage() {
         System.out.println(„Lesen Sie die Nachricht im Telegramm!“);
     }
}
WhatsApp:
public class WhatsApp implements Messenger {

    public void sendMessage() {

        System.out.println(„Eine WhatsApp-Nachricht senden!“);
    }

     public void getMessage() {
         System.out.println(„Eine WhatsApp-Nachricht lesen!“);
     }
}
Viber:
public class Viber implements Messenger {

    public void sendMessage() {

        System.out.println(„Eine Nachricht an Viber senden!“);
    }

     public void getMessage() {
         System.out.println(„Eine Nachricht in Viber lesen!“);
     }
}
Welche Vorteile bietet dies? Die wichtigste davon ist die lose Kopplung. Stellen Sie sich vor, wir entwerfen ein Programm, in dem wir Kundendaten sammeln. Die Klasse Clientmuss über ein Feld verfügen, das angibt, welchen Messenger der Client verwendet. Ohne Schnittstellen würde es seltsam aussehen:
public class Client {

    private WhatsApp whatsApp;
    private Telegram telegram;
    private Viber viber;
}
Wir haben drei Felder erstellt, aber ein Kunde kann problemlos nur einen Messenger haben. Wir wissen nur nicht, welches. Und um nicht ohne Kommunikation mit dem Kunden da zu bleiben, muss man alle möglichen Optionen in die Klasse „pushen“. Es stellt sich heraus, dass immer ein oder zwei davon vorhanden sein werden nullund dass sie überhaupt nicht benötigt werden, damit das Programm funktioniert. Nutzen Sie stattdessen besser unsere Schnittstelle:
public class Client {

    private Messenger messenger;
}
Dies ist ein Beispiel für „lose Kopplung“! Anstatt in der Klasse eine bestimmte Messenger-Klasse anzugeben Client, erwähnen wir einfach, dass der Client über einen Messenger verfügt. Welches davon wird im Laufe des Programms festgelegt. Aber warum brauchen wir dafür Schnittstellen? Warum wurden sie überhaupt zur Sprache hinzugefügt? Die Frage ist gut und richtig! Das gleiche Ergebnis kann mit der gewöhnlichen Vererbung erzielt werden, oder? Die Klasse Messengerist die übergeordnete Klasse und , Viberund Telegramsind WhatsAppdie Erben. Tatsächlich ist es möglich, dies zu tun. Aber es gibt einen Haken. Wie Sie bereits wissen, gibt es in Java keine Mehrfachvererbung. Es gibt jedoch mehrere Implementierungen von Schnittstellen. Eine Klasse kann beliebig viele Interfaces implementieren. Stellen Sie sich vor, wir haben eine Klasse Smartphonemit einem Feld Application– einer Anwendung, die auf einem Smartphone installiert ist.
public class Smartphone {

    private Application application;
}
Die Anwendung und der Messenger sind natürlich ähnlich, aber dennoch sind es unterschiedliche Dinge. Messenger kann sowohl mobil als auch auf dem Desktop sein, während Application eine mobile Anwendung ist. Wenn wir also die Vererbung verwenden würden, könnten wir Telegramder Klasse kein Objekt hinzufügen Smartphone. Schließlich kann eine Klasse nicht von und ab Telegramerben ! Und wir haben es bereits geschafft, es zu erben und in dieser Form zur Klasse hinzuzufügen . Aber eine Klasse kann problemlos beide Schnittstellen implementieren! Daher können wir in einer Klasse ein Objekt als und in einer Klasse als implementieren . So wird es gemacht: ApplicationMessengerMessengerClientTelegramClientTelegramMessengerSmartphoneApplication
public class Telegram implements Application, Messenger {

    //...Methoden
}

public class Client {

    private Messenger messenger;

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


public class Smartphone {

    private Application application;

    public Smartphone() {
        this.application = new Telegram();
    }
}
Jetzt können wir die Klasse Telegramnach Belieben nutzen. Irgendwo wird er in der Rolle von agieren Application, irgendwo in der Rolle von Messenger. Sie haben wahrscheinlich schon bemerkt, dass Methoden in Schnittstellen immer „leer“ sind, also keine Implementierung haben. Der Grund dafür ist einfach: Eine Schnittstelle beschreibt das Verhalten, nicht implementiert es. „Alle Objekte von Klassen, die die Schnittstelle implementieren, Swimmablemüssen schweben können“: Das ist alles, was uns die Schnittstelle sagt. Wie genau ein Fisch, eine Ente oder ein Pferd schwimmen wird, ist eine Frage der Klassen Fish, Duckund Horseund nicht der Schnittstelle. Genauso wie der Senderwechsel die Aufgabe eines Fernsehers ist. Die Fernbedienung bietet Ihnen lediglich eine Taste, um dies zu tun. Java8 verfügt jedoch über eine interessante Ergänzung – Standardmethoden. Ihre Schnittstelle verfügt beispielsweise über 10 Methoden. 9 davon sind in verschiedenen Klassen unterschiedlich implementiert, eine davon ist jedoch in allen gleich implementiert. Zuvor, vor der Veröffentlichung von Java8, hatten Methoden innerhalb von Schnittstellen überhaupt keine Implementierung: Der Compiler gab sofort einen Fehler aus. Jetzt können Sie es so machen:
public interface Swimmable {

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

   public void eat();

   public void run();
}
Mit dem Schlüsselwort defaulthaben wir in der Schnittstelle eine Methode mit einer Standardimplementierung erstellt. Wir müssen die beiden anderen Methoden eat()und run()selbst in allen Klassen implementieren, die implementieren werden Swimmable. Bei der Methode ist dies nicht erforderlich swim(): Die Implementierung ist in allen Klassen gleich. Übrigens sind Sie in den vergangenen Aufgaben schon öfter auf Schnittstellen gestoßen, obwohl Ihnen das selbst nicht aufgefallen ist :) Hier ein anschauliches Beispiel: Warum brauchen wir Schnittstellen in Java - 2Sie haben mit Schnittstellen gearbeitet Listund Set! Genauer gesagt, mit ihren Implementierungen – ArrayList, LinkedListund HashSetanderen. Das gleiche Diagramm zeigt ein Beispiel, wenn eine Klasse mehrere Schnittstellen gleichzeitig implementiert. Es implementiert beispielsweise LinkedListdie Schnittstellen Listund Deque(doppelseitige Warteschlange). Sie sind auch mit der Schnittstelle Mapbzw. deren Implementierungen vertraut HashMap. In diesem Diagramm sieht man übrigens eine Besonderheit: Schnittstellen können voneinander geerbt werden. Die Schnittstelle SortedMapwird von geerbt Mapund Dequewird von queue geerbt Queue. Dies ist erforderlich, wenn Sie die Verbindung zwischen Schnittstellen anzeigen möchten, eine Schnittstelle jedoch eine erweiterte Version einer anderen ist. Schauen wir uns ein Beispiel mit einer Schnittstelle an Queue– einer Warteschlange. Wir haben die Kollektionen noch nicht durchgesehen Queue, aber sie sind recht einfach und wie eine normale Reihe in einem Geschäft angeordnet. Sie können Elemente nur am Ende der Warteschlange hinzufügen und sie nur am Anfang entfernen. Zu einem bestimmten Zeitpunkt benötigten die Entwickler eine erweiterte Version der Warteschlange, damit Elemente hinzugefügt und von beiden Seiten empfangen werden konnten. So entstand eine Schnittstelle Deque– eine bidirektionale Warteschlange. Sie enthält alle Methoden einer regulären Warteschlange, da sie das „übergeordnete“ Element einer bidirektionalen Warteschlange ist, es wurden jedoch neue Methoden hinzugefügt.
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION