Unterschied zwischen Abstact-Klasse und Schnittstelle
- Abstrakte Klassen versus Schnittstellen in Java 8
- Konzeptioneller Unterschied:
Standardmethoden der Schnittstelle in Java 8
- Was ist die Standardmethode?
- Für jede Methode wurde ein Kompilierungsfehler mit der Standardmethode behoben
- Probleme mit der Standardmethode und Mehrdeutigkeit bei Mehrfachvererbung
- Wichtige Punkte zu den Standardmethoden der Java-Schnittstelle:
Statische Methode der Java-Schnittstelle
- Statische Methode der Java-Schnittstelle, Codebeispiel, statische Methode vs. Standardmethode
- Wichtige Punkte zur statischen Methode der Java-Schnittstelle:
Java-Funktionsschnittstellen
Abstrakte Klassen versus Schnittstellen in Java 8
Änderungen an der Java 8-Schnittstelle umfassen statische Methoden und Standardmethoden in Schnittstellen. Vor Java 8 konnten wir nur Methodendeklarationen in den Schnittstellen haben. Ab Java 8 können jedoch Standardmethoden und statische Methoden in den Schnittstellen vorhanden sein.
Nach der Einführung der Standardmethode scheinen Schnittstellen und abstrakte Klassen identisch zu sein. In Java 8 sind sie jedoch immer noch ein anderes Konzept.
Abstrakte Klasse kann Konstruktor definieren. Sie sind strukturierter und können mit einem Status verknüpft sein. Im Gegensatz dazu kann die Standardmethode nur durch Aufrufen anderer Schnittstellenmethoden implementiert werden, ohne dass auf den Status einer bestimmten Implementierung Bezug genommen wird. Daher hängt die Verwendung für verschiedene Zwecke und die Wahl zwischen zwei wirklich vom Szenariokontext ab.
Konzeptioneller Unterschied:
Abstrakte Klassen gelten für skelettartige (dh teilweise) Implementierungen von Schnittstellen, sollten jedoch ohne eine passende Schnittstelle nicht existieren.
Können abstrakte Klassen dies auch beseitigen, wenn abstrakte Klassen effektiv auf eine geringe Sichtbarkeit reduziert werden, Skelettimplementierungen von Schnittstellen? Entschlossen: Nein! Das Implementieren von Schnittstellen erfordert fast immer einige oder alle dieser Tools zum Erstellen von Klassen, die Standardmethoden fehlen. Und wenn einige Schnittstellen dies nicht tun, handelt es sich eindeutig um einen Sonderfall, der Sie nicht in die Irre führen sollte.
Standardmethoden der Schnittstelle in Java 8
Java 8 führt die neue Funktion " Standardmethode " oder (Verteidigungsmethoden) ein, mit der Entwickler den Schnittstellen neue Methoden hinzufügen können, ohne die vorhandene Implementierung dieser Schnittstelle zu beschädigen. Es bietet Flexibilität, um die Implementierung der Schnittstellendefinition zu ermöglichen, die standardmäßig verwendet wird, wenn eine konkrete Klasse keine Implementierung für diese Methode bereitstellt.
Betrachten wir ein kleines Beispiel, um zu verstehen, wie es funktioniert:
public interface OldInterface {
public void existingMethod();
default public void newDefaultMethod() {
System.out.println("New default method"
+ " is added in interface");
}
}
Die folgende Klasse wird erfolgreich in Java JDK 8 kompiliert:
public class OldInterfaceImpl implements OldInterface {
public void existingMethod() {
// existing implementation is here…
}
}
Wenn Sie eine Instanz von OldInterfaceImpl erstellen:
OldInterfaceImpl obj = new OldInterfaceImpl ();
// print “New default method add in interface”
obj.newDefaultMethod();
Standardmethoden sind niemals endgültig, können nicht synchronisiert werden und können die Methoden von Object nicht überschreiben. Sie sind immer öffentlich, was die Fähigkeit, kurze und wiederverwendbare Methoden zu schreiben, stark einschränkt.
Standardmethoden können einer Schnittstelle bereitgestellt werden, ohne die Implementierung von Klassen zu beeinflussen, da sie eine Implementierung enthält. Wenn jede hinzugefügte Methode in einer mit der Implementierung definierten Schnittstelle keine implementierende Klasse betrifft. Eine implementierende Klasse kann die von der Schnittstelle bereitgestellte Standardimplementierung überschreiben.
Standardmethoden ermöglichen das Hinzufügen neuer Funktionen zu vorhandenen Schnittstellen, ohne die ältere Implementierung dieser Schnittstellen zu beschädigen.
Wenn wir eine Schnittstelle erweitern, die eine Standardmethode enthält, können wir Folgendes ausführen:
- Überschreiben Sie die Standardmethode nicht und erben Sie die Standardmethode.
- Überschreiben Sie die Standardmethode ähnlich wie andere Methoden, die wir in der Unterklasse überschreiben.
- Deklarieren Sie die Standardmethode erneut als abstrakt, wodurch die Unterklasse gezwungen wird, sie zu überschreiben.
Für jede Methode wurde ein Kompilierungsfehler mit der Standardmethode behoben
Für Java 8 wurden die JDK-Sammlungen erweitert und die forEach-Methode zur gesamten Sammlung hinzugefügt (die in Verbindung mit Lambdas funktioniert). Auf herkömmliche Weise sieht der Code wie folgt aus:
public interface Iterable<T> {
public void forEach(Consumer<? super T> consumer);
}
Da dies zu jeder implementierenden Klasse mit Kompilierungsfehlern führt, wird eine Standardmethode mit einer erforderlichen Implementierung hinzugefügt, damit die vorhandene Implementierung nicht geändert wird.
Die iterierbare Schnittstelle mit der Standardmethode ist unten aufgeführt.
public interface Iterable<T> {
public default void forEach(Consumer
<? super T> consumer) {
for (T t : this) {
consumer.accept(t);
}
}
}
Der gleiche Mechanismus wurde verwendet, um Stream in der JDK-Schnittstelle hinzuzufügen, ohne die implementierenden Klassen zu beschädigen.
Probleme mit der Standardmethode und Mehrdeutigkeit bei Mehrfachvererbung
Da die Java-Klasse mehrere Schnittstellen implementieren kann und jede Schnittstelle eine Standardmethode mit derselben Methodensignatur definieren kann, können die geerbten Methoden miteinander in Konflikt stehen.
Betrachten Sie das folgende Beispiel:
public interface InterfaceA {
default void defaultMethod(){
System.out.println("Interface A default method");
}
}
public interface InterfaceB {
default void defaultMethod(){
System.out.println("Interface B default method");
}
}
public class Impl implements InterfaceA, InterfaceB {
}
Der obige Code kann mit dem folgenden Fehler nicht kompiliert werden:
java: class Impl erbt nicht verwandte Standardeinstellungen für defaultMethod () von den Typen InterfaceA und InterfaceB
Um diese Klasse zu reparieren, müssen wir die Standardmethodenimplementierung bereitstellen:
public class Impl implements InterfaceA, InterfaceB {
public void defaultMethod(){
}
}
Wenn wir die Standardimplementierung aufrufen möchten, die von einer der Super-Schnittstellen bereitgestellt wird, und nicht von unserer eigenen Implementierung, können wir dies wie folgt tun:
public class Impl implements InterfaceA, InterfaceB {
public void defaultMethod(){
// existing code here..
InterfaceA.super.defaultMethod();
}
}
Wir können im Rahmen unserer neuen Methode jede Standardimplementierung oder beides auswählen.
Wichtige Punkte zu den Standardmethoden der Java-Schnittstelle:
- Die Standardmethoden für Java-Schnittstellen helfen uns bei der Erweiterung von Schnittstellen, ohne befürchten zu müssen, Implementierungsklassen zu beschädigen.
- Die Standardmethoden für Java-Schnittstellen haben die Unterschiede zwischen Schnittstellen und abstrakten Klassen überbrückt.
- Die Standardmethoden der Java 8-Schnittstelle helfen uns dabei, Dienstprogrammklassen zu vermeiden, z. B. können alle Collections-Klassenmethoden in den Schnittstellen selbst bereitgestellt werden.
- Die Standardmethoden der Java-Schnittstelle helfen uns beim Entfernen von Basisimplementierungsklassen. Wir können die Standardimplementierung bereitstellen und die Implementierungsklassen können auswählen, welche überschrieben werden sollen.
- Einer der Hauptgründe für die Einführung von Standardmethoden in Schnittstellen ist die Erweiterung der Collections-API in Java 8 zur Unterstützung von Lambda-Ausdrücken.
- Wenn eine Klasse in der Hierarchie eine Methode mit derselben Signatur hat, sind Standardmethoden irrelevant. Eine Standardmethode kann eine Methode aus java.lang.Object nicht überschreiben. Die Argumentation ist sehr einfach, da Object die Basisklasse für alle Java-Klassen ist. Selbst wenn Objektklassenmethoden als Standardmethoden in Schnittstellen definiert sind, ist dies nutzlos, da immer die Objektklassenmethode verwendet wird. Um Verwirrung zu vermeiden, können wir keine Standardmethoden verwenden, die Objektklassenmethoden überschreiben.
- Standardmethoden für Java-Schnittstellen werden auch als Defender-Methoden oder virtuelle Erweiterungsmethoden bezeichnet.
Ressourcenlink:
- Schnittstelle mit Standardmethoden vs Abstract-Klasse in Java 8
- Abstrakte Klasse versus Schnittstelle in der JDK 8-Ära
- Schnittstellenentwicklung über virtuelle Erweiterungsmethoden
Statische Methode der Java-Schnittstelle
Statische Methode der Java-Schnittstelle, Codebeispiel, statische Methode vs. Standardmethode
Die statische Methode der Java-Schnittstelle ähnelt der Standardmethode, außer dass wir sie in den Implementierungsklassen nicht überschreiben können. Diese Funktion hilft uns dabei, unerwünschte Ergebnisse bei schlechter Implementierung in Implementierungsklassen zu vermeiden. Lassen Sie uns dies anhand eines einfachen Beispiels untersuchen.
public interface MyData {
default void print(String str) {
if (!isNull(str))
System.out.println("MyData Print::" + str);
}
static boolean isNull(String str) {
System.out.println("Interface Null Check");
return str == null ? true : "".equals(str) ? true : false;
}
}
Lassen Sie uns nun eine Implementierungsklasse sehen, die eine isNull () -Methode mit schlechter Implementierung hat.
public class MyDataImpl implements MyData {
public boolean isNull(String str) {
System.out.println("Impl Null Check");
return str == null ? true : false;
}
public static void main(String args[]){
MyDataImpl obj = new MyDataImpl();
obj.print("");
obj.isNull("abc");
}
}
Beachten Sie, dass isNull (String str) eine einfache Klassenmethode ist und die Schnittstellenmethode nicht überschreibt. Wenn wir beispielsweise der isNull () -Methode eine @ Override-Annotation hinzufügen, führt dies zu einem Compilerfehler.
Wenn wir nun die Anwendung ausführen, erhalten wir folgende Ausgabe.
Interface Null Check
Impl Null Check
Wenn wir die Schnittstellenmethode von statisch auf Standard setzen, erhalten wir folgende Ausgabe.
Impl Null Check
MyData Print ::
Impl Null Check
Die statische Methode der Java-Schnittstelle ist nur für Schnittstellenmethoden sichtbar. Wenn wir die Methode isNull () aus der MyDataImpl-Klasse entfernen, können wir sie nicht für das MyDataImpl-Objekt verwenden. Wie bei anderen statischen Methoden können wir jedoch statische Schnittstellenmethoden unter Verwendung des Klassennamens verwenden. Eine gültige Anweisung lautet beispielsweise:
boolean result = MyData.isNull("abc");
Wichtige Punkte zur statischen Methode der Java-Schnittstelle:
- Die statische Methode der Java-Schnittstelle ist Teil der Schnittstelle. Wir können sie nicht für Implementierungsklassenobjekte verwenden.
- Statische Methoden der Java-Schnittstelle eignen sich gut zur Bereitstellung von Dienstprogrammmethoden, z. B. Nullprüfung, Sortierung von Sammlungen usw.
- Die statische Methode der Java-Schnittstelle hilft uns bei der Bereitstellung von Sicherheit, indem Implementierungsklassen diese nicht überschreiben dürfen.
- Wir können keine statische Schnittstellenmethode für Objektklassenmethoden definieren. Wir erhalten den Compilerfehler "Diese statische Methode kann die Instanzmethode nicht vor Object verbergen". Dies liegt daran, dass dies in Java nicht zulässig ist, da Object die Basisklasse für alle Klassen ist und wir nicht über eine statische Methode auf Klassenebene und eine andere Instanzmethode mit derselben Signatur verfügen können.
- Wir können statische Methoden der Java-Schnittstelle verwenden, um Dienstprogrammklassen wie Sammlungen zu entfernen und alle statischen Methoden auf die entsprechende Schnittstelle zu verschieben, die leicht zu finden und zu verwenden wäre.
Java-Funktionsschnittstellen
Bevor ich den Beitrag abschließe, möchte ich eine kurze Einführung in funktionale Schnittstellen geben. Eine Schnittstelle mit genau einer abstrakten Methode wird als funktionale Schnittstelle bezeichnet.
Eine neue Anmerkung @FunctionalInterface
wurde eingeführt, um eine Schnittstelle als funktionale Schnittstelle zu markieren.@FunctionalInterface
Annotation ist eine Möglichkeit, das versehentliche Hinzufügen abstrakter Methoden zu den Funktionsschnittstellen zu vermeiden. Es ist optional, aber eine gute Praxis, es zu verwenden.
Funktionale Schnittstellen werden von Java 8 lange erwartet und sind sehr gefragt, da sie es uns ermöglichen, Lambda-Ausdrücke zu verwenden, um sie zu instanziieren. Ein neues Paket java.util.function mit einer Reihe von Funktionsschnittstellen wurde hinzugefügt, um Zieltypen für Lambda-Ausdrücke und Methodenreferenzen bereitzustellen. Wir werden uns in zukünftigen Beiträgen mit funktionalen Schnittstellen und Lambda-Ausdrücken befassen.
Ressourcenstandort:
- Java 8-Schnittstellenänderungen - statische Methode, Standardmethode