Mit Beispielen erläuterte Java-Schnittstellen

Schnittstellen

Die Schnittstelle in Java ist ein bisschen wie die Klasse, aber mit einem signifikanten Unterschied: Eine interfacekann nur Methodensignaturen, Felder und Standardmethoden haben. Seit Java 8 können Sie auch Standardmethoden erstellen. Im nächsten Block sehen Sie ein Beispiel für eine Schnittstelle:

public interface Vehicle { public String licensePlate = ""; public float maxVel public void start(); public void stop(); default void blowHorn(){ System.out.println("Blowing horn"); } }

Die obige Schnittstelle enthält zwei Felder, zwei Methoden und eine Standardmethode. Alleine ist es nicht sehr nützlich, aber sie werden normalerweise zusammen mit Klassen verwendet. Wie? Einfach, Sie müssen sicherstellen, dass einige Klasse implementses.

public class Car implements Vehicle { public void start() { System.out.println("starting engine..."); } public void stop() { System.out.println("stopping engine..."); } }

Nun gibt es eine Grundregel : Die Klasse muss alle Methoden in der Schnittstelle implementieren . Die Methoden müssen genau dieselbe Signatur (Name, Parameter und Ausnahmen) haben wie in der Schnittstelle beschrieben. Die Klasse muss jedoch nicht die Felder deklarieren, sondern nur die Methoden.

Instanzen einer Schnittstelle

Sobald Sie eine Java-Klasse für eine implementsbeliebige Schnittstelle erstellt haben, kann auf die Objektinstanz als Instanz der Schnittstelle verwiesen werden. Dieses Konzept ähnelt dem der Vererbungsinstanziierung.

// following our previous example Vehicle tesla = new Car(); tesla.start(); // starting engine ...

Eine Schnittstelle kann keine Konstruktormethoden enthalten. Daher können Sie selbst keine Instanz einer Schnittstelle erstellen. Sie müssen eine Instanz einer Klasse erstellen, die eine Schnittstelle implementiert, um darauf zu verweisen.

Stellen Sie sich Schnittstellen als leeres Vertragsformular oder als Vorlage vor.

Was können Sie mit dieser Funktion tun? Polymorphismus! Sie können nur Schnittstellen verwenden, um auf Objektinstanzen zu verweisen!

class Truck implements Vehicle { public void start() { System.out.println("starting truck engine..."); } public void stop() { System.out.println("stopping truck engine..."); } } class Starter { // static method, can be called without instantiating the class public static void startEngine(Vehicle vehicle) { vehicle.start(); } } Vehicle tesla = new Car(); Vehicle tata = new Truck(); Starter.startEngine(tesla); // starting engine ... Starter.startEngine(tata); // starting truck engine ...

Aber wie wäre es mit mehreren Schnittstellen?

Ja, Sie können mehrere Schnittstellen in einer Klasse implementieren. Während Sie bei der Vererbung innerhalb von Klassen nur eine Klasse erben durften, können Sie hier eine beliebige Anzahl von Schnittstellen erweitern. Vergessen Sie jedoch nicht, alle Methoden aller Schnittstellen zu implementieren , da sonst die Kompilierung fehlschlägt!

public interface GPS { public void getCoordinates(); } public interface Radio { public void startRadio(); public void stopRadio(); } public class Smartphone implements GPS,Radio { public void getCoordinates() { // return some coordinates } public void startRadio() { // start Radio } public void stopRadio() { // stop Radio } }

Einige Funktionen von Schnittstellen

  • Sie können Variablen in eine Schnittstelle einfügen, obwohl dies keine sinnvolle Entscheidung ist, da Klassen nicht an dieselbe Variable gebunden sind. Kurz gesagt, vermeiden Sie das Platzieren von Variablen!
  • Alle Variablen und Methoden in einer Schnittstelle sind öffentlich, auch wenn Sie das publicSchlüsselwort weglassen.
  • Eine Schnittstelle kann die Implementierung einer bestimmten Methode nicht angeben. Es liegt an den Klassen, dies zu tun. Obwohl es kürzlich eine Ausnahme gegeben hat (siehe unten).
  • Wenn eine Klasse mehrere Schnittstellen implementiert, besteht eine geringe Wahrscheinlichkeit einer Überlappung der Methodensignaturen. Da Java nicht mehrere Methoden mit genau derselben Signatur zulässt, kann dies zu Problemen führen. Weitere Informationen finden Sie in dieser Frage.

Standardmethoden der Schnittstelle

Vor Java 8 hatten wir keine Möglichkeit, eine Schnittstelle für eine bestimmte Methodenimplementierung anzuweisen. Dies führt zu großer Verwirrung und Codebrüchen, wenn eine Schnittstellendefinition plötzlich geändert wird.

Angenommen, Sie haben eine Open Source-Bibliothek geschrieben, die eine Schnittstelle enthält. Angenommen, Ihre Kunden, dh praktisch alle Entwickler auf der ganzen Welt, nutzen es stark und sind glücklich. Jetzt mussten Sie die Bibliothek aktualisieren, indem Sie der Schnittstelle eine neue Methodendefinition hinzufügen, um eine neue Funktion zu unterstützen. Dies würde jedoch alle Builds beschädigen, da sich alle Klassen, die diese Schnittstelle implementieren, jetzt ändern müssen. Was für eine Katastrophe!

Zum Glück bietet uns Java 8 jetzt defaultMethoden für Schnittstellen. Eine defaultMethode kann eine eigene Implementierung direkt in der Schnittstelle enthalten! Wenn eine Klasse keine Standardmethode implementiert, übernimmt der Compiler die in der Schnittstelle erwähnte Implementierung. Schön, nicht wahr? Sie können also in Ihrer Bibliothek eine beliebige Anzahl von Standardmethoden in Schnittstellen hinzufügen, ohne befürchten zu müssen, dass etwas kaputt geht!

public interface GPS { public void getCoordinates(); default public void getRoughCoordinates() { // implementation to return coordinates from rough sources // such as wifi & mobile System.out.println("Fetching rough coordinates..."); } } public interface Radio { public void startRadio(); public void stopRadio(); } public class Smartphone implements GPS,Radio { public void getCoordinates() { // return some coordinates } public void startRadio() { // start Radio } public void stopRadio() { // stop Radio } // no implementation of getRoughCoordinates() } Smartphone motoG = new Smartphone(); motog.getRoughCoordinates(); // Fetching rough coordinates...

Was passiert jedoch, wenn zwei Schnittstellen dieselbe Methodensignatur haben?

Tolle Frage. In diesem Fall wird ein schlechter Compiler verwirrt und schlägt einfach fehl, wenn Sie die Implementierung in der Klasse nicht bereitstellen! Sie müssen auch eine Standardmethodenimplementierung innerhalb der Klasse bereitstellen. Es gibt auch eine raffinierte Möglichkeit super, die von Ihnen gewünschte Implementierung aufzurufen:

public interface Radio { // public void startRadio(); // public void stopRadio(); default public void next() { System.out.println("Next from Radio"); } } public interface MusicPlayer { // public void start(); // public void pause(); // public void stop(); default public void next() { System.out.println("Next from MusicPlayer"); } } public class Smartphone implements Radio, MusicPlayer { public void next() { // Suppose you want to call MusicPlayer next MusicPlayer.super.next(); } } Smartphone motoG = new Smartphone(); motoG.next(); // Next from MusicPlayer

Statische Methoden in Schnittstellen

Ebenfalls neu in Java 8 ist die Möglichkeit, Schnittstellen statische Methoden hinzuzufügen. Statische Methoden in Schnittstellen sind nahezu identisch mit statischen Methoden in konkreten Klassen. Der einzige große Unterschied besteht darin, dass staticMethoden nicht in den Klassen vererbt werden, die die Schnittstelle implementieren. Dies bedeutet, dass beim Aufrufen der statischen Methode auf die Schnittstelle verwiesen wird, nicht auf die Klasse, die sie implementiert.

interface MusicPlayer { public static void commercial(String sponsor) { System.out.println("Now for a message brought to you by " + sponsor); } public void play(); } class Smartphone implements MusicPlayer { public void play() { System.out.println("Playing from smartphone"); } } class Main { public static void main(String[] args) { Smartphone motoG = new Smartphone(); MusicPlayer.commercial("Motorola"); // Called on interface not on implementing class // motoG.commercial("Motorola"); // This would cause a compilation error } }

Eine Schnittstelle erben

In Java ist es auch möglich, dass eine Schnittstelle eine andere Schnittstelle erbt , indem Sie das extendsSchlüsselwort verwenden:

public interface Player { public void start(); public void pause(); public void stop(); } public interface MusicPlayer extends Player { default public void next() { System.out.println("Next from MusicPlayer"); } }

Das bedeutet, dass die Umsetzung der Klasse MusicPlayerSchnittstelle zu implementieren , hat alle Methoden MusicPlayersowie Player:

public class SmartPhone implements MusicPlayer { public void start() { System.out.println("start"); } public void stop() { System.out.println("stop"); } public void pause() { System.out.println("pause"); } }

Jetzt haben Sie einen guten Überblick über Java-Schnittstellen! Erfahren Sie mehr über abstrakte Klassen, um zu sehen, wie Java Ihnen eine weitere Möglichkeit bietet, Verträge zu definieren.