it-swarm.com.de

Schnittstelle mit Standardmethoden vs. Abstract-Klasse in Java 8

Da Java 8 die Standardimplementierung von Methoden in der Schnittstelle mit dem Namen Default Methods ermöglicht, scheint es eine Verwirrung zu geben, wann ich einen abstract class verwenden würde.

Wann sollte also eine Schnittstelle mit Standardmethoden verwendet werden und wann sollte eine abstrakte Klasse verwendet werden? Sind die abstrakten Klassen in diesem Szenario noch nützlich? 

415
Narendra Pathai

Es gibt eine Menge mehr für abstrakte Klassen als für Standardmethodenimplementierungen (z. B. privater Status), aber ab Java 8 sollten Sie, wenn Sie die Wahl haben, die Methode defender (aka. default) in der Benutzeroberfläche verwenden.

Die Einschränkung der Standardmethode besteht darin, dass sie nur in Form von Aufrufen zu anderen Schnittstellenmethoden ohne Bezug auf den Status einer bestimmten Implementierung implementiert werden kann. Der Hauptanwendungsfall ist also eine übergeordnete Methode und eine bequemere Methode.

Das Gute an dieser neuen Funktion ist, dass, wo Sie zuvor gezwungen waren, eine abstrakte Klasse für die Convenience-Methoden zu verwenden und somit den Implementierer auf eine einzelne Vererbung zu beschränken, jetzt ein wirklich sauberes Design mit nur der Schnittstelle und einem Minimum an Implementierung vorhanden ist Mühe auf den Programmierer gezwungen.

Die ursprüngliche Motivation, default-Methoden in Java 8 einzuführen, war der Wunsch, die Collections Framework-Schnittstellen mit Lambda-orientierten Methoden zu erweitern, ohne vorhandene Implementierungen zu brechen. Obwohl dies für die Autoren öffentlicher Bibliotheken relevanter ist, kann dieselbe Funktion auch in Ihrem Projekt nützlich sein. Es gibt einen zentralen Ort, an dem Sie neue Bequemlichkeiten hinzufügen können, und Sie müssen sich nicht darauf verlassen, wie der Rest der Typhierarchie aussieht.

246
Marko Topolnik

Es gibt einige technische Unterschiede. Abstrakte Klassen können im Vergleich zu Java 8-Schnittstellen noch mehr leisten:

  1. Eine abstrakte Klasse kann einen Konstruktor haben.
  2. Abstrakte Klassen sind strukturierter und können einen Staat enthalten.

Konzeptionell ist der Hauptzweck von Defender-Methoden eine Abwärtskompatibilität nach Einführung neuer Funktionen (als Lambda-Funktionen) in Java 8.

96
Vadym Vasyliev

Dies wird in diesem Artikel beschrieben. Denken Sie an forEach von Collections.

List<?> list = …
list.forEach(…);

Das forEach wird weder von Java.util.List noch von .__ deklariert. Java.util.Collection interface schon. Eine naheliegende Lösung wäre Fügen Sie einfach die neue Methode der vorhandenen Schnittstelle hinzu und geben Sie die .__ an. Implementierung, wo dies im JDK erforderlich ist. Einmal veröffentlicht, ist es Es ist unmöglich, einer Schnittstelle Methoden hinzuzufügen, ohne die .__ zu beschädigen. bestehende Implementierung.

Der Vorteil von Standardmethoden ist, dass es jetzt möglich ist, Fügen Sie der Schnittstelle eine neue Standardmethode hinzu, und die .__-Datei wird nicht beschädigt. Implementierungen.

58
Masudul

Wie in diesem Artikel beschrieben,

Abstrakte Klassen versus Schnittstellen in Java 8

Nach der Einführung der Default-Methode scheinen Schnittstellen und abstrakte Klassen sind gleich. Sie sind jedoch immer noch ein anderes Konzept in Java 8.

Eine abstrakte Klasse kann einen Konstruktor definieren. Sie sind strukturierter und kann einen Zustand haben, der mit ihnen verbunden ist. Im Gegensatz dazu default Die Methode kann nur in Bezug auf das Aufrufen anderer .__ implementiert werden. Schnittstellenmethoden ohne Bezug auf eine bestimmte Implementierung Zustand. Daher verwenden beide für unterschiedliche Zwecke und die Wahl zwischen zwei hängt wirklich vom Szenario-Kontext ab.

15
Sufiyan Ghori

Diese beiden sind sehr unterschiedlich:

Standardmethoden sind fügen Sie externe Funktionalität hinzu zu vorhandenen Klassen, ohne ihren Status zu ändern.

Und abstrakte Klassen sind eine normale Art der Vererbung. Sie sind normale Klassen, die erweitert werden sollen.

14
Andrey Chaschev

Zu Ihrer Frage von 

Wann sollte also eine Schnittstelle mit Standardmethoden verwendet werden und wann sollte eine abstrakte Klasse verwendet werden? Sind die abstrakten Klassen in diesem Szenario noch nützlich?

Java Dokumentation liefert die perfekte Antwort. 

Abstrakte Klassen im Vergleich zu Schnittstellen:

Abstrakte Klassen sind Schnittstellen ähnlich. Sie können sie nicht instanziieren, und sie enthalten möglicherweise eine Mischung von Methoden, die mit oder ohne Implementierung deklariert wurden. 

Mit abstrakten Klassen können Sie jedoch Felder deklarieren, die nicht statisch und endgültig sind, und öffentliche, geschützte und private konkrete Methoden definieren.

Bei Schnittstellen sind alle Felder automatisch public, static und final. Alle Methoden, die Sie deklarieren oder definieren (als Standardmethoden), sind public. Außerdem können Sie nur eine Klasse erweitern, unabhängig davon, ob sie abstrakt ist oder nicht, während Sie eine beliebige Anzahl von Schnittstellen implementieren können.

Anwendungsfälle für jeden von ihnen wurden im Folgenden beschrieben:

Was ist der Unterschied zwischen einer Schnittstelle und einer abstrakten Klasse?

Sind die abstrakten Klassen in diesem Szenario noch nützlich?

Ja. Sie sind immer noch nützlich. Sie sind können nicht statische, nicht endgültige Methoden enthaltenund Attribute (geschützt, privat zusätzlich zu public), was selbst mit Java-8-Schnittstellen nicht möglich ist. 

12
Ravindra babu

Wann immer wir zwischen abstrakten Klassen und Schnittstellen wählen können, sollten wir (fast) Standardmethoden (auch als Verteidiger oder virtuelle Erweiterungen bezeichnet) bevorzugen.

  1. Standardmethoden haben dem klassischen Interface-Muster ein Ende gesetzt und eine Companion-Klasse, die die meisten oder alle Methoden in diesem Interface implementiert. Ein Beispiel ist Collection and AbstractCollection. Jetzt sollten wir die Methoden in der Schnittstelle selbst implementieren, um die Standardfunktionalität bereitzustellen. Die Klassen, die die Schnittstelle implementieren, haben die Wahl, die Methoden zu überschreiben oder die Standardimplementierung zu erben.
  2. Eine weitere wichtige Verwendung von Standardmethoden ist interface evolution. Angenommen, ich hatte einen Klassenball als:

    public class Ball implements Collection { ... }

In Java 8 wurde nun ein neues Feature-Stream eingeführt. Wir können einen Stream abrufen, indem Sie die stream-Methode der Schnittstelle hinzufügen. Wenn stream keine Standardmethode wäre, wären alle Implementierungen für Collection-Schnittstelle fehlerhaft, da sie diese neue Methode nicht implementieren würden. Das Hinzufügen einer nicht standardmäßigen Methode zu einer Schnittstelle ist nicht source-compatible.

Nehmen wir jedoch an, wir kompilieren die Klasse nicht neu und verwenden eine alte JAR-Datei, die diese Klasse Ball enthält. Die Klasse wird ohne diese fehlende Methode problemlos geladen, Instanzen können erstellt werden und es scheint, dass alles einwandfrei funktioniert.ABERWenn das Programm die stream-Methode in der Instanz von Ball aufruft, erhalten wir AbstractMethodError. Wenn Sie die Methode als Standard festlegen, wurden beide Probleme gelöst.

11
i_am_zero

Standardmethoden in der Java-Schnittstelle ermöglichen die Entwicklung von interface.

Wenn Sie bei vorhandener Schnittstelle eine Methode hinzufügen möchten, ohne die binäre Kompatibilität mit älteren Versionen der Schnittstelle zu unterbrechen, haben Sie zwei Möglichkeiten: Eine Standardmethode oder eine statische Methode hinzufügen. In der Tat müsste jede der Schnittstelle hinzugefügte abstrakte Methode von den Klassen oder Schnittstellen implementiert werden, die diese Schnittstelle implementieren.

Eine statische Methode ist für eine Klasse eindeutig. Eine Standardmethode ist für eine Instanz der Klasse eindeutig.

Wenn Sie einer vorhandenen Schnittstelle eine Standardmethode hinzufügen, müssen Klassen und Schnittstellen, die diese Schnittstelle implementieren, diese nicht implementieren. Sie können

  • implementieren Sie die Standardmethode und überschreibt die Implementierung in der implementierten Schnittstelle.
  • die Methode erneut deklarieren (ohne Implementierung), wodurch sie abstrakt wird.
  • tun Sie nichts (dann wird die Standardmethode der implementierten Schnittstelle einfach vererbt).

Mehr zum Thema hier .

6
octoback

Remi Forax Regel ist Sie entwerfen nicht mit abstrakten Klassen. Sie gestalten Ihre App mit Schnittstellen. Was auch immer die Version von Java ist, welche Sprache auch immer. Es wird durch die Prinzipien I interfacesegregationin SOLI D unterstützt.

Sie können später abstrakte Klassen verwenden, um Code zu faktorisieren. Mit Java 8 können Sie es jetzt direkt in der Benutzeroberfläche tun. Dies ist eine Einrichtung, nicht mehr.

4
Nicolas Zozol

wann sollte eine Schnittstelle mit Standardmethoden verwendet werden und wann sollte ein abstrakte Klasse verwendet werden?

Abwärtskompatibilität: Stellen Sie sich vor, Ihre Schnittstelle wird von Hunderten von Klassen implementiert. Wenn Sie diese Schnittstelle ändern, müssen alle Benutzer die neu hinzugefügte Methode implementieren, auch wenn dies für viele andere Klassen, die Ihre implementieren, nicht unbedingt erforderlich ist Schnittstelle, Plus ermöglicht es Ihrer Schnittstelle, einefunktionale Schnittstelle zu sein

Fakten und Einschränkungen:  

1-Darf nur innerhalb einer Schnittstelle und nicht innerhalb einer Klasse oder einer abstrakten Klasse .__ deklariert werden.

2-Muss einen Körper zur Verfügung stellen

3-Es wird nicht angenommen, dass es abstrakt ist, wie andere normale Methoden, die in einer Schnittstelle verwendet werden.

1
Ahmad Sanie

In Java 8 sieht eine Schnittstelle wie eine abstrakte Klasse aus, obwohl einige Unterschiede bestehen können:

1) Abstrakte Klassen sind Klassen. Sie sind daher nicht auf andere Einschränkungen der Schnittstelle in Java beschränkt, z. abstrakte Klasse kann den Status haben, aber Sie können den Status auf der Schnittstelle in Java nicht haben.

2) Ein weiterer semantischer Unterschied zwischen der Schnittstelle mit Standardmethoden und der abstrakten Klasse besteht darin, dass Sie Konstruktoren innerhalb einer abstrakten Klasse definieren können

0
Manish Sahni

Wie in anderen Antworten erwähnt, wurde die Möglichkeit zum Hinzufügen einer Implementierung zu einer Schnittstelle hinzugefügt, um Abwärtskompatibilität im Collections-Framework zu gewährleisten. Ich würde argumentieren, dass die Bereitstellung von Abwärtskompatibilität möglicherweise der einzige gute Grund für das Hinzufügen von Implementierung zu einer Schnittstelle ist.

Andernfalls: Wenn Sie einer Schnittstelle eine Implementierung hinzufügen, verstoßen Sie gegen das Grundgesetz dafür, warum Schnittstellen überhaupt hinzugefügt wurden. Java ist im Gegensatz zu C++ eine einzelne Vererbungssprache, die dies zulässt zur Mehrfachvererbung. Schnittstellen bieten die Tippvorteile einer Sprache, die Mehrfachvererbung unterstützt, ohne die Probleme einzuführen, die mit Mehrfachvererbung einhergehen.

Insbesondere erlaubt Java nur die einmalige Vererbung einer Implementierung, jedoch die mehrfache Vererbung von Schnittstellen. Das Folgende ist beispielsweise gültiger Java Code:

class MyObject extends String implements Runnable, Comparable { ... }

MyObject erbt nur eine Implementierung, aber drei Verträge.

Java hat die mehrfache Vererbung von Implementierungen weitergegeben, da die mehrfache Vererbung von Implementierungen mit einer Vielzahl heikler Probleme einhergeht, die außerhalb des Bereichs dieser Antwort liegen. Es wurden Schnittstellen hinzugefügt, um die mehrfache Vererbung von Verträgen (auch als Schnittstellen bezeichnet) zu ermöglichen, ohne die Probleme einer mehrfachen Vererbung der Implementierung.

Um meinen Standpunkt zu unterstützen, hier ein Zitat von Ken Arnold und James Gosling aus dem Buch The Java Programming Language, 4. Auflage :

Einzelne Vererbung schließt einige nützliche und korrekte Designs aus. Die Probleme der Mehrfachvererbung ergeben sich aus der Mehrfachvererbung der Implementierung, aber in vielen Fällen wird die Mehrfachvererbung verwendet, um mehrere abstrakte Verträge und möglicherweise eine konkrete Implementierung zu erben. Die Bereitstellung eines Mittels zum Erben eines abstrakten Vertrags ohne Erben einer Implementierung ermöglicht die Typisierung von Vorteilen einer Mehrfachvererbung ohne die Probleme einer Mehrfachvererbung der Implementierung. Die Vererbung eines abstrakten Vertrags wird als Schnittstellenvererbung bezeichnet. Die Programmiersprache Java unterstützt die Schnittstellenvererbung, indem Sie einen interface -Typ deklarieren können

0
johnnyodonnell

Bitte denken Sie zuerst an den offenen/geschlossenen Grundsatz. Die Standardmethoden in Interfaces VERLETZEN es. Dies ist eine schlechte Funktion in Java. Es fördert schlechtes Design, schlechte Architektur und niedrige Softwarequalität. Ich würde vorschlagen, die Verwendung von Standardmethoden vollständig zu vermeiden.

Stellen Sie sich ein paar Fragen: Warum können Sie Ihre Methoden nicht der abstrakten Klasse zuordnen? Benötigen Sie dann mehr als eine abstrakte Klasse? Dann überlegen Sie, wofür Ihre Klasse verantwortlich ist. Sind Sie sicher, dass alle Methoden, die Sie für die einzelne Klasse einsetzen werden, wirklich den gleichen Zweck erfüllen? Möglicherweise unterscheiden Sie mehrere Zwecke und teilen dann Ihre Klasse in mehrere Klassen auf, für jeden Zweck eine eigene Klasse.

0
mentallurg

Standardmethoden in Java Interface werden eher verwendet, um eine Dummy-Implementierung einer Funktion bereitzustellen. Dadurch wird jede implementierende Klasse dieser Schnittstelle vor dem Verzicht auf die Deklaration aller abstrakten Methoden geschützt, auch wenn sie nur mit einer ..__ Schnittstelle ist somit in gewisser Weise ein Ersatz für das Konzept der Adapterklassen.

Die Methoden in der abstrakten Klasse sollen jedoch eine sinnvolle Implementierung ergeben, die jede untergeordnete Klasse nur dann überschreiben darf, wenn sie zum Überschreiben einer gemeinsamen Funktionalität benötigt wird.

0
shubh