630 Stimmen

Wann verwenden: Java 8+ Interface-Standardmethode vs. abstrakte Methode

Java 8 ermöglicht die Standardimplementierung von Methoden in Interfaces, die als Default Methods bezeichnet werden.

Ich bin verwirrt darüber, wann ich diese Art von Interface-Standardmethode verwenden sollte, anstelle einer abstrakten Klasse (mit abstrakten Methoden).

Wann sollte ein Interface mit Standardmethoden verwendet werden und wann sollte eine abstrakte Klasse (mit abstrakten Methoden) verwendet werden? Sind die abstrakten Klassen in diesem Szenario immer noch nützlich?

2voto

Ahmad Sanie Punkte 3658

wann sollten Schnittstellen mit Standardmethoden verwendet werden und wann sollte eine abstrakte Klasse verwendet werden?

Rückwärtskompatibilität: Stellen Sie sich vor, dass Ihre Schnittstelle von Hunderten von Klassen implementiert wird. Die Modifikation dieser Schnittstelle zwingt alle Benutzer, die neu hinzugefügte Methode zu implementieren, auch wenn sie für viele andere Klassen, die Ihre Schnittstelle implementieren, nicht unbedingt erforderlich ist. Außerdem ermöglicht es Ihrer Schnittstelle, eine funktionale Schnittstelle zu sein.

Fakten & Einschränkungen:

1-Kann nur innerhalb einer Schnittstelle erklärt werden und nicht innerhalb einer Klasse oder abstrakten Klasse.

2-Muss einen Körper bereitstellen

3-Wird nicht als abstrakt angenommen wie andere normale Methoden, die in einer Schnittstelle verwendet werden.

1voto

Manish Sahni Punkte 488

In Java 8 sieht eine Schnittstelle wie eine abstrakte Klasse aus, obwohl es einige Unterschiede geben kann, wie :

1) Abstrakte Klassen sind Klassen, daher sind sie nicht den anderen Beschränkungen der Schnittstelle in Java unterworfen, z.B. abstrakte Klasse kann den Zustand haben, aber Sie können den Zustand auf der Schnittstelle in Java nicht haben.

2) Ein weiterer semantischer Unterschied zwischen Schnittstelle mit Standardmethoden und abstrakter Klasse ist, dass Sie Konstruktoren innerhalb einer abstrakten Klasse definieren können, aber Sie können in Java keinen Konstruktor innerhalb einer Schnittstelle definieren.

0voto

anik Punkte 155

Standardmethoden in Java Interface sollen eher zur Bereitstellung einer Dummy-Implementierung einer Funktion verwendet werden, um so jeder implementierenden Klasse dieses Interfaces die Schmerzen zu ersparen, alle abstrakten Methoden zu deklarieren, auch wenn sie nur mit einer umgehen möchten. Standardmethoden im Interface sind also in gewisser Weise mehr ein Ersatz für das Konzept der Adapterklassen.

Die Methoden in einer abstrakten Klasse sollen jedoch eine sinnvolle Implementierung liefern, die jede Kindklasse nur überschreiben sollte, wenn sie eine gemeinsame Funktionalität überschreiben muss.

0voto

johnnyodonnell Punkte 1770

Wie in anderen Antworten erwähnt, wurde die Möglichkeit, Implementierungen zu einer Schnittstelle hinzuzufügen, hinzugefügt, um Abwärtskompatibilität im Collections-Framework zu ermöglichen. Ich würde behaupten, dass die Bereitstellung von Abwärtskompatibilität möglicherweise der einzige gute Grund ist, um Implementierungen zu einer Schnittstelle hinzuzufügen.

Ansonsten, wenn Sie Implementierungen zu einer Schnittstelle hinzufügen, brechen Sie das grundlegende Gesetz, warum Schnittstellen überhaupt hinzugefügt wurden. Java ist eine Single-Inheritance-Sprache, im Gegensatz zu C++, das mehrfache Vererbung zulässt. Schnittstellen bieten die Vorteile der Typisierung, die mit einer Sprache, die mehrere Vererbung unterstützt, einhergehen, ohne die Probleme der mehrfachen Vererbung einzuführen.

Konkret erlaubt Java nur die Einzelvererbung einer Implementierung, gestattet jedoch die Mehrfachvererbung von Schnittstellen. Zum Beispiel ist der folgende Java-Code gültig:

class MyObject erweitert String implementiert Runnable, Comparable { ... }

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

Java verzichtete auf die Mehrfachvererbung von Implementierungen, weil damit eine Vielzahl von komplizierten Problemen einhergeht, die den Rahmen dieser Antwort sprengen. Schnittstellen wurden hinzugefügt, um die Mehrfachvererbung von Verträgen (auch bekannt als Schnittstellen) zu ermöglichen, ohne die Probleme der Mehrfachvererbung von Implementierungen zu verursachen.

Zur Unterstützung meines Standpunkts hier ein Zitat von Ken Arnold und James Gosling aus dem Buch Die Java-Programmiersprache, 4. Ausgabe:

Die Einzelvererbung schließt einige nützliche und korrekte Designs aus. Die Probleme der Mehrfachvererbung ergeben sich aus der Mehrfachvererbung von Implementierungen, aber in vielen Fällen wird Mehrfachvererbung verwendet, um eine Reihe von abstrakten Verträgen und vielleicht eine konkrete Implementierung zu erben. Die Möglichkeit, einen abstrakten Vertrag zu erben, ohne eine Implementierung zu übernehmen, ermöglicht die Vorteile der Typisierung bei Mehrfachvererbung, ohne die Probleme der Mehrfachimplementierungsvererbung. Die Vererbung eines abstrakten Vertrags wird als _Schnittstellenerb_ung bezeichnet. Die Java-Programmiersprache unterstützt die Schnittstellenerb durch die Deklaration eines Schnittstelle-Typs

0voto

Alferd Nobel Punkte 1845

Aus einem Geschäftsfallkontext heraus können Schnittstellen verwendet werden, um spezifische Geschäftsregeln zu definieren, während eine abstrakte Klasse die gemeinsame Struktur definieren würde, um das Geschäft anzukurbeln.

Angenommen, ein Geschäftsinhaber möchte mit Amazon und Walmart zusammenarbeiten, dann würden die hier definierten Schnittstellen WalmartPartner und AmazonPartner die spezifischen Geschäftsregeln definieren und die abstrakte Klasse BusinessSetup das Geschäft in einer spezifischen Region aufsetzen.

// Schnittstellen

public interface WalmartPartner {
    public static boolean signUpForWalmartBusinessAccount(String BusinessId){
        System.out.println("Einstellung des Walmart-Geschäftspartners");
        return true;
    }
    public default  void  getWalmartDeals(){
        System.out.println("Standard-Walmart-Angebot wird ausgeführt!");
    }
    public abstract void setupShopifyForWalmart();
    public abstract  void setupWalmartProducts();

public interface AmazonPartner {
    public static boolean signUpAsAmazonServicePartner(String BusinessId){
        System.out.println("Einrichtung des Amazon-Geschäftspartners");
        return true;
    }
    public default  void  paymentPlatformSetup(){
        System.out.println("Das Standard-Zahlungsplattform von Amazon ist eingerichtet");
    }
    public abstract void setupPrimeMemberDealsByRegion();
    public abstract  void setupPrimeDeals();
}

 // Abstrakte Klasse 

public abstract class BusinessSetup {
    String businessId ;
    public BusinessSetup(String businessId){
        this.businessId = businessId;
        System.out.println("1. Die initiale Geschäftseinrichtung für BusienssID: "+this.businessId+" ist abgeschlossen");
    }
    public final boolean getBusinessRegisteredInRegion(String region){
        System.out.println("2. Das Geschäft wurde in "+region+ " registriert!");
        return true;
    }
    public abstract void setupCustomerPlatform(String customerId);
    public abstract void setupVendorPlatform(String vendorId);

}

// Konkrete Klasse
public class WalMartPartnerImpl extends BusinessSetup implements WalmartPartner {
    public WalMartPartnerImpl(String businessId) {
        super(businessId);
    }
    @Override
    public void setupCustomerPlatform(String customerId) {
    }

    @Override
    public void setupVendorPlatform(String vendorId) {
    }

    @Override
    public void setupShopifyForWalmart() {
    }

    @Override
    public void setupWalmartProducts() {
    }
    public static void main(String args[]){
        WalMartPartnerImpl walMartPartner = new WalMartPartnerImpl("wal8989");
        walMartPartner.getBusinessRegisteredInRegion("Kalifornien");
        walMartPartner.getWalmartDeals();
        walMartPartner.setupCustomerPlatform("wal8989");

    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X