Java Interfaces verstehen: Definitionen, Verwendung und Best Practices
Was ist ein Interface?
Ein Interface ist ein Referenztyp in Java. Es ist ähnlich wie eine Klasse. Es ist eine Sammlung von abstrakten Methoden. Eine Klasse implementiert ein Interface und erbt dadurch die abstrakten Methoden des Interfaces.
Zusammen mit abstrakten Methoden kann ein Interface auch Konstanten, Default-Methoden, statische Methoden und verschachtelte Typen enthalten. Methodenbodys existieren nur für Default-Methoden und statische Methoden.
Das Schreiben eines Interfaces ist ähnlich wie das Schreiben einer Klasse. Aber eine Klasse beschreibt die Attribute und das Verhalten eines Objekts. Ein Interface enthält Verhaltensweisen, die eine Klasse implementiert.
Es sei denn, die Klasse, die das Interface implementiert, ist abstrakt, müssen alle Methoden des Interfaces in der Klasse definiert werden.
Ähnlichkeiten zwischen Interface und Klasse
- Ein Interface kann beliebig viele Methoden enthalten.
- Ein Interface wird in einer Datei mit der Erweiterung .java geschrieben, wobei der Name des Interfaces dem Dateinamen entsprechen muss.
- Der Bytecode eines Interfaces erscheint in einer .class-Datei.
- Interfaces erscheinen in Paketen, und ihre entsprechende Bytecode-Datei muss in einer Verzeichnisstruktur liegen, die dem Paketnamen entspricht.
Unterschiede zwischen Interface und Klasse
- Sie können ein Interface nicht instanziieren.
- Ein Interface enthält keine Konstruktoren.
- Alle Methoden in einem Interface sind abstrakt (implizit).
- Ein Interface kann keine Instanzfelder enthalten. Die einzigen Felder, die in einem Interface auftreten können, müssen sowohl
staticals auchfinaldeklariert sein. - Ein Interface wird nicht von einer Klasse erweitert (extended); es wird von einer Klasse implementiert.
- Ein Interface kann mehrere Interfaces erweitern.
Interfaces deklarieren
Das Schlüsselwort interface wird verwendet, um ein Interface zu deklarieren. Hier ist ein einfaches Beispiel:
Beispiel
/* Dateiname: NameOfInterface.java */
import java.lang.*; // Beliebig viele Import-Statements
public interface NameOfInterface {
// Beliebig viele final, static Felder
// Beliebig viele abstrakte Methodendeklarationen
}
Interfaces haben folgende Eigenschaften:
- Ein Interface ist implizit abstrakt. Sie müssen das
abstract-Schlüsselwort nicht bei der Deklaration eines Interfaces verwenden. - Jede Methode in einem Interface ist ebenfalls implizit abstrakt, daher ist das
abstract-Schlüsselwort nicht erforderlich. - Methoden in einem Interface sind implizit public.
Beispiel: Animal Interface
/* Dateiname: Animal.java */
interface Animal {
public void eat();
public void travel();
}
Interfaces implementieren
Wenn eine Klasse ein Interface implementiert, können Sie sich die Klasse als einen Vertrag vorstellen, der zustimmt, die spezifischen Verhaltensweisen des Interfaces auszuführen. Wenn eine Klasse nicht alle Verhaltensweisen des Interfaces ausführt, muss die Klasse sich selbst als abstrakt deklarieren.
Eine Klasse verwendet das Schlüsselwort implements, um ein Interface zu implementieren. Das implements-Schlüsselwort erscheint in der Klassendeklaration nach dem extends-Teil der Deklaration.
Beispiel
/* 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();
}
}
Ausgabe:
Mammal eats
Mammal travels
Beim Überschreiben von in Interfaces definierten Methoden sind folgende Regeln zu beachten:
- Checked Exceptions sollten in Implementierungsmethoden nicht deklariert werden, außer denen, die von der Interface-Methode oder Unterklassen der von der Interface-Methode deklarierten Exceptions deklariert wurden.
- Die Signatur der Interface-Methode und derselbe Rückgabetyp oder Subtyp sollten beim Überschreiben der Methoden beibehalten werden.
- Eine Implementierungsklasse kann selbst abstrakt sein, und wenn dies der Fall ist, müssen Interface-Methoden nicht implementiert werden.
Bei der Implementierung von Interfaces gelten folgende Regeln:
- Eine Klasse kann mehr als ein Interface gleichzeitig implementieren.
- Eine Klasse kann nur eine Klasse erweitern, aber viele Interfaces implementieren.
- Ein Interface kann ein anderes Interface erweitern, ähnlich wie eine Klasse eine andere Klasse erweitern kann.
Interfaces erweitern (Extending Interfaces)
Ein Interface kann ein anderes Interface auf die gleiche Weise erweitern, wie eine Klasse eine andere Klasse erweitern kann. Das Schlüsselwort extends wird verwendet, um ein Interface zu erweitern, und das Kind-Interface erbt die Methoden des Eltern-Interfaces.
Das folgende Sports-Interface wird von Hockey und Football Interfaces erweitert.
Beispiel
// 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 hat vier Methoden, aber es erbt zwei von Sports; somit muss eine Klasse, die Hockey implementiert, alle sechs Methoden implementieren. Ähnlich muss eine Klasse, die Football implementiert, die drei Methoden von Football und die zwei Methoden von Sports definieren.
Mehrere Interfaces erweitern (Extending Multiple Interfaces)
Eine Java-Klasse kann nur eine Elternklasse erweitern. Multiple Vererbung ist nicht erlaubt. Interfaces sind jedoch keine Klassen, und ein Interface kann mehr als ein Eltern-Interface erweitern.
Beispielsweise, wenn das Hockey-Interface sowohl Sports als auch Event erweitern würde, wäre es wie folgt deklariert:
Beispiel
public interface Hockey extends Sports, Event
Tagging Interfaces (Markierungs-Interfaces)
Die häufigste Verwendung der Erweiterung von Interfaces tritt auf, wenn das Eltern-Interface keine Methoden enthält. Zum Beispiel wurde das MouseListener-Interface im java.awt.event-Paket von java.util.EventListener erweitert, das wie folgt definiert ist:
Beispiel
package java.util;
public interface EventListener { }
Ein Interface ohne Methoden wird als Tagging-Interface (Markierungs-Interface) bezeichnet. Es gibt zwei grundlegende Designzwecke von Tagging-Interfaces:
Einen gemeinsamen Elternteil erstellen – Wie beim EventListener-Interface, das von Dutzenden anderer Interfaces in der Java-API erweitert wird, können Sie ein Tagging-Interface verwenden, um einen gemeinsamen Elternteil unter einer Gruppe von Interfaces zu erstellen. Zum Beispiel weiß die JVM, wenn ein Interface EventListener erweitert, dass dieses bestimmte Interface in einem Event-Delegations-Szenario verwendet wird.
Einen Datentyp zu einer Klasse hinzufügen – Hier kommt der Begriff "Tagging" her. Eine Klasse, die ein Tagging-Interface implementiert, muss keine Methoden definieren (da das Interface keine hat), aber die Klasse wird durch Polymorphie zu einem Interface-Typ.
Java
- Javas final-Schlüsselwort verstehen: Variablen, Methoden und Klassen
- Java instanceof-Operator: Ein umfassender Leitfaden
- Java-Schnittstellen meistern: Konzepte, Implementierung und Best Practices
- Java statische verschachtelte Klassen verstehen: Nutzung, Unterschiede und Beispiele
- Java anonyme innere Klassen meistern: Definition, Syntax und praktische Beispiele
- Java Singleton-Pattern erklärt: Sichere Implementierung und Verwendung
- Java Reflection meistern: Klassen, Methoden und Felder zur Laufzeit inspizieren
- Java ObjectOutputStream meistern: Serialisierung, Methoden und praktische Beispiele
- Java Generics meistern – Wiederverwendbaren, typsicheren Code erstellen
- Java-Dateioperationen mit java.io meistern – Erstellen, Lesen, Schreiben & Löschen