Java-Schnittstelle

Eine Schnittstelle (englisch: Interface) in der Programmiersprache Java ist ein abstrakter Typ, eine Sammlung abstrakter Methoden. Schnittstellen werden üblicherweise mit dem Schlüsselwort `interface` deklariert. Eine Klasse erbt die abstrakten Methoden einer Schnittstelle, indem sie die Schnittstelle implementiert.

Eine Schnittstelle ist keine Klasse. Das Schreiben einer Schnittstelle ähnelt dem Schreiben einer Klasse, aber sie sind unterschiedliche Konzepte. Eine Klasse beschreibt die Eigenschaften und Methoden eines Objekts. Eine Schnittstelle enthält Methoden, die eine Klasse implementieren muss.

Sofern die Klasse, die die Schnittstelle implementiert, keine abstrakte Klasse ist, muss die Klasse alle Methoden der Schnittstelle definieren.

Schnittstellen können nicht instanziiert werden, aber sie können implementiert werden. Eine Klasse, die eine Schnittstelle implementiert, muss alle in der Schnittstelle beschriebenen Methoden implementieren, andernfalls muss sie als abstrakte Klasse deklariert werden. Darüber hinaus können in Java Schnittstellentypen verwendet werden, um Variablen zu deklarieren. Sie können ein Nullzeiger sein oder an ein Objekt gebunden werden, das diese Schnittstelle implementiert.

Ähnlichkeiten zwischen Schnittstellen und Klassen:

  • Eine Schnittstelle kann mehrere Methoden haben.
  • Schnittstellendateien werden in Dateien mit der Endung .java gespeichert, und der Dateiname verwendet den Namen der Schnittstelle.
  • Die Bytecode-Datei einer Schnittstelle wird in einer Datei mit der Endung .class gespeichert.
  • Die zugehörige Bytecode-Datei einer Schnittstelle muss sich in einer Verzeichnisstruktur befinden, die dem Paketnamen entspricht.

Unterschiede zwischen Schnittstellen und Klassen:

  • Schnittstellen können nicht zum Instanziieren von Objekten verwendet werden.
  • Schnittstellen haben keine Konstruktoren.
  • Alle Methoden in einer Schnittstelle müssen abstrakte Methoden sein. Seit Java 8 können Schnittstellen nicht-abstrakte Methoden haben, die mit dem Schlüsselwort `default` gekennzeichnet sind.
  • Schnittstellen dürfen keine Membervariablen enthalten, außer `static`- und `final`-Variablen.
  • Schnittstellen werden nicht von Klassen geerbt, sondern von Klassen implementiert.
  • Schnittstellen unterstützen Mehrfachvererbung.

Merkmale von Schnittstellen

  • Jede Methode in einer Schnittstelle ist ebenfalls implizit abstrakt. Methoden in einer Schnittstelle sind implizit alspublic abstractfestgelegt (nur `public abstract`; jeder andere Modifizierer führt zu einem Fehler.)
  • Schnittstellen können Variablen enthalten, aber Variablen in einer Schnittstelle sind implizit alspublic static finalVariablen festgelegt (und nur `public`; die Verwendung von `private` führt zu einem Kompilierungsfehler).
  • Methoden in einer Schnittstelle können nicht in der Schnittstelle implementiert werden; sie können nur von der Klasse implementiert werden, die die Schnittstelle implementiert.

Unterschied zwischen abstrakten Klassen und Schnittstellen

  • 1. Methoden in einer abstrakten Klasse können einen Methodenkörper haben, das heißt, sie können die spezifische Funktionalität der Methode implementieren, aber Methoden in einer Schnittstelle können das nicht.
  • 2. Membervariablen in einer abstrakten Klasse können verschiedene Typen haben, während Membervariablen in einer Schnittstelle nur den Typpublic static finalhaben können.
  • 3. Schnittstellen dürfen keine statischen Codeblöcke und keine statischen Methoden (mit `static` modifizierte Methoden) enthalten, aber abstrakte Klassen können statische Codeblöcke und statische Methoden haben.
  • 4. Eine Klasse kann nur von einer abstrakten Klasse erben, aber eine Klasse kann mehrere Schnittstellen implementieren.

Hinweis: Seit JDK 1.8 können Schnittstellen statische Methoden und Methodenkörper haben.

Hinweis: Seit JDK 1.8 dürfen Interfaces Methoden mit konkreten Implementierungen enthalten, die als "Default-Methoden" bezeichnet werden. Default-Methoden werden mit dem Schlüsselwort `default` gekennzeichnet. Weitere Informationen finden Sie unterJava 8 Default Methods。

Hinweis: Seit JDK 1.9 dürfen Methoden als privat definiert werden, damit wiederverwendbarer Code keine Methoden offenlegt. Weitere Informationen finden Sie unterJava 9 Private Interface Methods。


Deklaration von Interfaces

Die Syntax zum Deklarieren eines Interfaces lautet wie folgt:

[Sichtbarkeit] interfaceInterface-Name[extendsandere Interface-Namen] { //Variablen deklarieren //abstrakte Methoden }

Das Schlüsselwort `interface` wird verwendet, um ein Interface zu deklarieren. Nachfolgend finden Sie ein einfaches Beispiel für eine Interface-Deklaration.

Code der Datei NameOfInterface.java:

/*Dateiname: NameOfInterface.java*/ import java.lang.*; //Pakete importieren public interface NameOfInterface { //Beliebige finale, statische Felder //Abstrakte Methoden }
Interfaces haben die folgenden Eigenschaften:
  • Schnittstellen sind implizit abstrakt. Beim Deklarieren einer Schnittstelle ist es nicht nötig, das Schlüsselwortabstractzu verwenden.
  • Jede Methode in einer Schnittstelle ist ebenfalls implizit abstrakt. Beim Deklarieren benötigt man ebenfalls nicht das Schlüsselwortabstract.
  • Methoden in einer Schnittstelle sind alle public.

Beispiel

Code der Datei Animal.java:

/*Dateiname: Animal.java*/ interface Animal { public void eat(); public void travel(); }

Implementierung von Schnittstellen

Wenn eine Klasse eine Schnittstelle implementiert, muss die Klasse alle Methoden in der Schnittstelle implementieren. Andernfalls muss die Klasse als abstrakte Klasse deklariert werden.

Eine Klasse verwendet das Schlüsselwort `implements`, um eine Schnittstelle zu implementieren. In einer Klassendeklaration wird das Schlüsselwort `implements` nach der `class`-Deklaration platziert.

Die Syntax zum Implementieren einer Schnittstelle kann diese Formel verwenden:

Syntax der Schnittstelle:

...implementsSchnittstellenname[, andere Schnittstellennamen, andere Schnittstellennamen..., ...] ...

Beispiel

MammalInt.java Dateicode:

/*Dateiname: MammalInt.java*/ public class MammalInt implements Animal{ public void eat(){ System.out.println("Mammal eats"); } public void travel(){ System.out.println("Mammal travels"); } public int noOfLegs(){ return 0; } public static void main(String args[]){ MammalInt m = new MammalInt(); m.eat(); m.travel(); } }

Das Kompilierungs- und Ausführungsergebnis des obigen Beispiels ist wie folgt:

Mammal eats
Mammal travels

Beim Überschreiben von in einer Schnittstelle deklarierten Methoden müssen Sie die folgenden Regeln beachten:

  • Wenn eine Klasse eine Schnittstellenmethode implementiert, kann sie keine obligatorische Ausnahme werfen; die obligatorische Ausnahme kann nur in der Schnittstelle oder in der abstrakten Klasse, die die Schnittstelle erbt, geworfen werden.
  • Beim Überschreiben einer Methode muss die Klasse denselben Methodennamen beibehalten und sollte denselben oder einen kompatiblen Rückgabetyp beibehalten.
  • Wenn die Klasse, die das Interface implementiert, eine abstrakte Klasse ist, besteht keine Notwendigkeit, die Methoden des Interfaces zu implementieren.

Beim Implementieren eines Interfaces sind außerdem einige Regeln zu beachten:

  • Eine Klasse kann mehrere Interfaces gleichzeitig implementieren.
  • Eine Klasse kann nur von einer Klasse erben, aber mehrere Interfaces implementieren.
  • Ein Interface kann ein anderes Interface erben, was der Vererbung zwischen Klassen ähnelt.

Vererbung von Interfaces

Ein Interface kann ein anderes Interface erben, was der Vererbung zwischen Klassen ähnelt. Die Interface-Vererbung verwendet das Schlüsselwort `extends`, und ein Unterinterface erbt die Methoden des übergeordneten Interfaces.

Das folgende Interface Sports wird von den Interfaces Hockey und Football geerbt:

//Dateiname: Sports.java public interface Sports { public void setHomeTeam(String name); public void setVisitingTeam(String name); } //Dateiname: Football.java public interface Football extends Sports { public void homeTeamScored(int points); public void visitingTeamScored(int points); public void endOfQuarter(int quarter); } //Dateiname: Hockey.java public interface Hockey extends Sports { public void homeGoalScored(); public void visitingGoalScored(); public void endOfPeriod(int period); public void overtimePeriod(int ot); }

Das Hockey-Interface deklariert selbst vier Methoden und erbt zwei Methoden vom Sports-Interface. Auf diese Weise muss eine Klasse, die das Hockey-Interface implementiert, sechs Methoden implementieren.

Ähnlich muss eine Klasse, die das Football-Interface implementiert, fünf Methoden implementieren, von denen zwei vom Sports-Interface stammen.


Mehrfachvererbung von Interfaces

In Java ist Mehrfachvererbung von Klassen unzulässig, aber Interfaces erlauben Mehrfachvererbung.

Bei der Mehrfachvererbung von Interfaces muss das Schlüsselwort `extends` nur einmal verwendet werden, gefolgt von den geerbten Interfaces. Wie unten gezeigt:

public interface Hockey extends Sports, Ereignis

Das obige Programmfragment ist ein gültig definiertes Sub-Interface. Im Gegensatz zu Klassen erlauben Interfaces Mehrfachvererbung, und Sports und Event können dieselben Methoden definieren oder erben.


Marker-Interfaces

Das am häufigsten verwendete Marker-Interface ist ein Interface, das keine Methoden enthält.

Ein Marker-Interface ist ein Interface ohne Methoden oder Eigenschaften. Es zeigt lediglich an, dass seine Klasse zu einem bestimmten Typ gehört, damit anderer Code dies testen und zulassen kann, dass bestimmte Dinge getan werden.

Zweck eines Marker-Interface: einfach und bildhaft gesagt, ein Objekt mit einer Kennzeichnung (einem Stempel) zu versehen, wodurch das Objekt bestimmte Privilegien erhält.

Zum Beispiel: Das Interface java.util.EventListener, das vom MouseListener-Interface im Paket java.awt.event geerbt wird, ist wie folgt definiert:

package java.util; public interface EventListener {}

Ein Interface ohne jegliche Methoden wird als Marker-Interface bezeichnet. Marker-Interfaces werden hauptsächlich für die folgenden zwei Zwecke verwendet:

  • Ein gemeinsames übergeordnetes Interface einrichten:

    So wie die EventListener-Schnittstelle, eine Java-API, die von Dutzenden anderer Schnittstellen erweitert wird, können Sie eine Marker-Schnittstelle verwenden, um eine übergeordnete Schnittstelle für eine Gruppe von Schnittstellen festzulegen. Zum Beispiel: Wenn eine Schnittstelle die EventListener-Schnittstelle erbt, weiß die Java Virtual Machine (JVM), dass diese Schnittstelle in einem Event-Delegationsschema verwendet wird.

  • Fügen Sie einer Klasse einen Datentyp hinzu:

    Diese Situation ist der ursprüngliche Zweck von Marker-Schnittstellen. Eine Klasse, die eine Marker-Schnittstelle implementiert, muss keine Schnittstellenmethoden definieren (weil eine Marker-Schnittstelle einfach keine Methoden hat), aber die Klasse wird durch Polymorphie zu einem Schnittstellentyp.

Weitere Erweiterungen