2015-07-23 11 views
52

Eine Schnittstelle in Java ist eine Klasse ähnlich, aber der Körper einer Schnittstelle kann nur abstrakte Methoden und final Felder (Konstanten) umfassen.Was ist der Zweck des Standardschlüsselworts in Java?

Vor kurzem sah ich eine Frage, die wie diese

interface AnInterface { 
    public default void myMethod() { 
     System.out.println("D"); 
    } 
} 

Gemäß der Schnittstellen-Definition sieht, nur abstrakte Methoden sind erlaubt. Warum kann ich den obigen Code kompilieren? Wie lautet das Schlüsselwort default?

Auf der anderen Seite, wenn ich unten Code zu schreiben versuche, dann sagt es modifier default not allowed here

default class MyClass{ 

} 

statt

class MyClass { 

} 

Kann mir jemand sagen, den Zweck des default Schlüsselwort? Ist es nur innerhalb einer Schnittstelle erlaubt? Wie unterscheidet es sich von default (kein Zugriffsmodifikator)?

+4

Standardmethoden in Schnittstellen wurden in Java 8 hinzugefügt. Es ist kein Zugriffsmodifikator, es ist eine Standardimplementierung. – Eran

+2

@Eran denken Sie nicht, Einführung der Standardmethode verletzt Schnittstellendefinition? : s – Ravi

+2

Es hat die Schnittstellendefinition geändert. Diese Definition ist jetzt veraltet. –

Antwort

41

Es ist eine neue Funktion in Java 8, die eine interface ermöglicht, eine Implementierung bereitzustellen. Beschrieben in Java 8 JLS-13.5.6. Interface Method Declarations, die (teilweise) lesen

ein default Verfahren hinzufügen, oder eine Methode aus abstractdefault zu ändern, brechen nicht die Kompatibilität mit bereits bestehenden Binärdateien, kann aber ein IncompatibleClassChangeError wenn ein Pre- verursachen vorhandene binäre Versuche, die Methode aufzurufen. Dieser Fehler tritt auf, wenn die Qualifikation Typ, T, ein Subtyp von zwei Schnittstellen ist, I und J, wo beide I und J eine default Methode mit der gleichen Signatur und Ergebnis zu erklären, und weder I noch J ist ein Subschnittstelle des andere.

What's New in JDK 8 sagt (teilweise)

Standardmethoden neue Funktionen ermöglichen die Schnittstellen von Bibliotheken und gewährleisten die binäre Kompatibilität mit Code für ältere Versionen dieser Schnittstellen geschrieben hinzugefügt werden.

+10

Es scheint, jetzt Interface und abstrakte Klasse sind fast gleich. :) – Ravi

+1

@jWeaver Sie können beide jetzt Methodenimplementierungen bereitstellen. Es gibt auch verbesserte Typinferenz- und Lambda-Ausdrücke (syntaktischer Zucker ist süß). –

+7

@jWeaver-Schnittstellen können immer noch keine Konstruktoren, Felder, private Methoden oder Implementierungen von equals/hashCode/toString haben. –

2

Mit Standardmethoden können Sie den Schnittstellen Ihrer Apps neue Funktionen hinzufügen. Es kann auch verwendet werden, um eine Mehrfachvererbung zu haben. Zusätzlich zu Standardmethoden können Sie statische Methoden in Schnittstellen definieren. Dies erleichtert Ihnen die Organisation von Hilfsmethoden.

8

In Java 8 wird ein neues Konzept namens Standardmethoden eingeführt. Standardmethoden sind solche Methoden, die eine Standardimplementierung haben und beim Entwickeln der Schnittstellen helfen, ohne den vorhandenen Code zu unterbrechen.Schauen wir uns ein Beispiel:

public interface SimpleInterface { 
    public void doSomeWork(); 

    //A default method in the interface created using "default" keyword 

    default public void doSomeOtherWork(){ 

    System.out.println("DoSomeOtherWork implementation in the interface"); 
     } 
    } 

class SimpleInterfaceImpl implements SimpleInterface{ 

    @Override 
    public void doSomeWork() { 
    System.out.println("Do Some Work implementation in the class"); 
    } 

/* 
    * Not required to override to provide an implementation 
    * for doSomeOtherWork. 
    */ 

public static void main(String[] args) { 
    SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl(); 
    simpObj.doSomeWork(); 
    simpObj.doSomeOtherWork(); 
     } 
    } 

und der Ausgang ist:

Sie einige Arbeits Implementierung in der Klasse
DoSomeOtherWork Implementierung in der Schnittstelle

15

Standardmethoden wurden in Java 8 in erster Linie auf Lambda-Ausdrücke unterstützen. Die Designer (meiner Meinung nach klugerweise) entschieden sich dafür, eine lambdas-Syntax zu erstellen, um anonyme Implementierungen einer Schnittstelle zu erstellen. Da Lambdas jedoch nur eine einzige Methode implementieren können, würden sie sich auf Schnittstellen mit einer einzigen Methode beschränken, was eine ziemlich starke Einschränkung wäre. Stattdessen wurden Standardmethoden hinzugefügt, damit komplexere Schnittstellen verwendet werden können.

Wenn Sie etwas überzeugend von der Behauptung, dass default aufgrund lambdas eingeführt wurde, beachten Sie, dass die straw many proposal von Project Lambda, von Mark Reinhold, im Jahr 2009 erwähnt ‚Erweiterungsmethoden‘ als obligatorisches Merkmal lambda hinzugefügt werden, zu unterstützen .

Hier ist ein Beispiel, das zeigt das Konzept:

interface Operator { 
    int operate(int n); 
    default int inverse(int n) { 
     return -operate(n); 
    } 
} 

public int applyInverse(int n, Operator operator) { 
    return operator.inverse(n); 
} 

applyInverse(3, n -> n * n + 7); 

Sehr gekünstelt Mir ist klar, aber sollte zeigen, wie default lambdas unterstützt. Da inverse eine Standardeinstellung ist, kann sie bei Bedarf leicht von einer implementierenden Klasse überschrieben werden.

+3

Das ist nicht wirklich richtig. Lambdas mag die naheliegende Ursache sein, aber sie waren wirklich nur der Strohhalm, der das Fass zum Überlaufen brachte. Die eigentliche Motivation war die Ermöglichung der _Interface-Evolution_ (die es ermöglicht, vorhandene Schnittstellen kompatibel zu entwickeln, um neues Verhalten zu unterstützen); lambdas mag der Faktor gewesen sein, der dieses Bedürfnis in den Vordergrund stellte, aber das Merkmal ist allgemeiner. –

+0

@BrianGoetz: IMHO hätten sowohl Java als auch .NET enorm profitiert, wenn von Anfang an Standardmethoden existierten. Wenn eine allgemeine Operation bei jeder Implementierung einer Schnittstelle unter Verwendung nur von Schnittstellenelementen durchgeführt werden könnte, aber einige Implementierungen wahrscheinlich eine effizientere Möglichkeit hätten, diese auszuführen, sollte die Schnittstelle Methoden für diese Operationen definieren und Standardimplementierungen für sie bereitstellen. Die Unfähigkeit, Standardimplementierungen zu spezifizieren, hat den Druck erzeugt, dass Schnittstellen derartige Methoden auslassen, und hat es unmöglich gemacht, sie später hinzuzufügen. – supercat

+0

@BrianGoetz Ich stimme zu Standardmethoden haben einen signifikanten Wert über Lambdas hinaus. Aber ich würde mich für jeden Hinweis interessieren, den Sie zu diesem breiteren Wert geben können, der die Entscheidung antreibt, sie einzuschließen. Meine Lektüre ist, dass Lambdas der Hauptgrund waren (weshalb ich das Wort "hauptsächlich" in meiner Antwort verwendete). – sprinter

2

Die neue Java 8 Funktion (Default Methods) ermöglicht eine Schnittstelle eine Implementierung zur Verfügung zu stellen, wenn sein mit dem Schlüsselwort default gekennzeichnet.

Beispiel:

interface Test { 
    default double getAvg(int avg) { 
     return avg; 
    } 
} 
class Tester implements Test{ 
//compiles just fine 
} 

Interface Test verwendet den Standard Schlüsselwort, das die Schnittstelle ohne die Notwendigkeit, eine Standardimplementierung des Verfahrens zu schaffen, ermöglicht diese Methoden in den Klassen für die Implementierung, die die Schnittstelle verwendet.

Abwärtskompatibilität: Stellen Sie sich vor, dass Ihre Schnittstelle von Hunderten von Klassen implementiert wird, diese Schnittstelle modifiziert werden alle Benutzer zwingen, die neu hinzugefügte Methode zu implementieren, auch wenn es nicht wesentlich für viele andere Klassen, die Ihre Schnittstelle implementiert.

Fakten & Einschränkungen:

1-Mai nur innerhalb einer Schnittstelle und nicht innerhalb einer Klasse oder abstrakte Klasse deklariert werden.

2-Muss einem Körper liefert

3-It nicht angenommen wird, öffentlich oder abstrakt als andere normale Methoden in einer Schnittstelle verwendet werden.

2

Eine sehr gute Erklärung in The Java™ Tutorials gefunden wird, ein Teil der Erklärung ist wie folgt:

Beispiel betrachten, dass die Hersteller von computergesteuerten Autos beinhaltet die Industrie-Standard-Schnittstellen zu veröffentlichen, die beschreiben, welche Methoden können aufgerufen werden, betreiben ihre Autos.Was wäre, wenn diese computergesteuerten Autohersteller ihren Autos neue Funktionen wie den Flug hinzufügen würden? Diese Hersteller müssten neue Methoden festlegen, damit andere Unternehmen (z. B. Hersteller von elektronischen Wegmessinstrumenten) ihre Software an fliegende Autos anpassen können. Wo würden diese Autohersteller diese neuen flugbezogenen Methoden deklarieren? Wenn sie sie zu ihren ursprünglichen Schnittstellen hinzufügen, müssten Programmierer, die diese Schnittstellen implementiert haben, ihre Implementierungen neu schreiben. Wenn sie sie als statische Methoden hinzufügen, würden sie von Programmierern als Hilfsmethoden und nicht als wesentliche Kernmethoden betrachtet.

Mit Standardmethoden können Sie den Schnittstellen Ihrer Bibliotheken neue Funktionen hinzufügen und Binärkompatibilität mit Code sicherstellen, der für ältere Versionen dieser Schnittstellen geschrieben wurde.

0

Etwas, das in den obigen Antworten übersehen wurde, war seine Rolle in Annotationen. So weit zurück wie Java 1.5, kam das Schlüsselwort default als Mittel zu provide a default value für ein Anmerkungsfeld.

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.TYPE) 
public @interface Processor { 
    String value() default "AMD"; 
} 

Es Nutzung war überlastet mit der Einführung von Java 8 eine zu ermöglichen, eine Standardmethode in Schnittstellen zu definieren.

Etwas anderes, das übersehen wurde: der Grund, dass die Deklaration default class MyClass {} ungültig ist, ist aufgrund der Art, dass classes are declared at all. In der Sprache gibt es keine Bestimmung, die die Anzeige dieses Keywords ermöglicht. Es erscheint jedoch für interface method declarations, obwohl.

Verwandte Themen