Das Thema sagt das meiste aus - was ist der Grund dafür, dass statische Methoden in einer Schnittstelle nicht deklariert werden können?
public interface ITest {
public static String test();
}
Der obige Code gibt mir den folgenden Fehler (zumindest in Eclipse): "Unzulässiger Modifikator für die Schnittstellenmethode ITest.test (); nur public & abstract sind zulässig".
Antworten:
Hier spielen einige Probleme eine Rolle. Das erste ist das Problem, eine statische Methode zu deklarieren, ohne sie zu definieren. Das ist der Unterschied zwischen
und
Das erste ist aus den von Espo genannten Gründen unmöglich : Sie wissen nicht, welche implementierende Klasse die richtige Definition ist.
Java könnte Letzteres zulassen; und in der Tat, ab Java 8, tut es!
quelle
static
Methoden in einem definiereninterface
. Die Methoden müssen seinpublic
.Der Grund, warum Sie keine statische Methode in einer Schnittstelle haben können, liegt in der Art und Weise, wie Java statische Referenzen auflöst. Java wird sich nicht die Mühe machen, nach einer Instanz einer Klasse zu suchen, wenn versucht wird, eine statische Methode auszuführen. Dies liegt daran, dass statische Methoden nicht instanzabhängig sind und daher direkt aus der Klassendatei ausgeführt werden können. Da alle Methoden in einer Schnittstelle abstrakt sind, müsste die VM nach einer bestimmten Implementierung der Schnittstelle suchen, um den Code hinter der statischen Methode zu finden, damit sie ausgeführt werden kann. Dies widerspricht dann der Funktionsweise der statischen Methodenauflösung und würde zu einer Inkonsistenz in der Sprache führen.
quelle
Ich werde Ihre Frage mit einem Beispiel beantworten. Angenommen, wir hätten eine Matheklasse mit einer statischen Methode hinzufügen. Sie würden diese Methode folgendermaßen aufrufen:
Wenn Math eine Schnittstelle anstelle einer Klasse wäre, könnte es keine definierten Funktionen haben. Daher macht es keinen Sinn, etwas wie Math.add (2, 3) zu sagen.
quelle
Der Grund liegt im Design-Prinzip, dass Java keine Mehrfachvererbung zulässt. Das Problem der Mehrfachvererbung kann anhand des folgenden Beispiels veranschaulicht werden:
Was passiert nun, wenn Sie Cx () aufrufen? Wird Ax () oder Bx () ausgeführt? Jede Sprache mit Mehrfachvererbung muss dieses Problem lösen.
Schnittstellen ermöglichen in Java eine Art eingeschränkte Mehrfachvererbung. Um das oben genannte Problem zu vermeiden, dürfen sie keine Methoden haben. Wenn wir das gleiche Problem mit Schnittstellen und statischen Methoden betrachten:
Gleiches Problem hier, was passiert, wenn Sie Cx () aufrufen?
quelle
A
enthaltenint x(int z);
und SchnittstelleB
enthältstring x(int x);
? Was bedeutet diex(3)
Schnittstelle C?Statische Methoden sind keine Instanzmethoden. Es gibt keinen Instanzkontext, daher ist es wenig sinnvoll, ihn über die Schnittstelle zu implementieren.
quelle
Mit Java8 können wir jetzt sogar statische Methoden in Interface definieren.
Hinweis: Methoden in der Schnittstelle sind standardmäßig immer noch öffentlich abstrakt, wenn wir die Schlüsselwörter default / static nicht explizit verwenden, um sie zu Standardmethoden bzw. statischen Methoden zu machen.
quelle
Es ist eine sehr schöne und prägnante Antwort auf Ihre Frage hier . (Es kam mir so einfach vor, es zu erklären, dass ich es von hier aus verlinken möchte.)
quelle
Es scheint, dass die statische Methode in der Schnittstelle in Java 8 unterstützt wird. Meine Lösung besteht darin, sie nur in der inneren Klasse zu definieren.
Dieselbe Technik kann auch in Anmerkungen verwendet werden:
Auf die innere Klasse sollte immer in Form von zugegriffen werden,
Interface.fn...
anstatt dassClass.fn...
Sie dann mehrdeutige Probleme beseitigen können.quelle
Für den Polymorphismus wird eine Schnittstelle verwendet, die für Objekte und nicht für Typen gilt. Daher ist es (wie bereits erwähnt) nicht sinnvoll, ein statisches Schnittstellenmitglied zu haben.
quelle
Java 8 hat die Welt verändert. Sie können statische Methoden in der Schnittstelle haben, aber es zwingt Sie, die Implementierung dafür bereitzustellen.
}}
quelle
Illegale Kombination von Modifikatoren: statisch und abstrakt
Wenn ein Mitglied einer Klasse als statisch deklariert ist, kann es mit seinem auf diese Klasse beschränkten Klassennamen verwendet werden, ohne ein Objekt zu erstellen.
Wenn ein Mitglied einer Klasse als abstrakt deklariert ist, müssen Sie die Klasse als abstrakt deklarieren und die Implementierung des abstrakten Mitglieds in seiner geerbten Klasse (Unterklasse) bereitstellen.
Sie müssen dem abstrakten Element einer Klasse in einer Unterklasse eine Implementierung bereitstellen, in der Sie das Verhalten der statischen Methode ändern, die ebenfalls als abstrakt deklariert ist und auf die Basisklasse beschränkt ist, was nicht korrekt ist
quelle
Da statische Methoden nicht vererbt werden können. Es macht also keinen Sinn, es in die Benutzeroberfläche zu stellen. Interface ist im Grunde ein Vertrag, dem alle Abonnenten folgen müssen. Wenn Sie eine statische Methode in die Schnittstelle einfügen, werden die Abonnenten gezwungen, sie zu implementieren. Dies widerspricht nun der Tatsache, dass statische Methoden nicht vererbt werden können.
quelle
Zum Beispiel hat Comparator eine statische naturalOrder () -Methode.
Die Anforderung, dass Schnittstellen keine Implementierungen haben dürfen, wurde ebenfalls gelockert. Schnittstellen können jetzt "Standard" -Methodenimplementierungen deklarieren, die mit einer Ausnahme wie normale Implementierungen sind: Wenn Sie sowohl eine Standardimplementierung von einer Schnittstelle als auch eine normale Implementierung von einer Oberklasse erben, hat die Implementierung der Oberklasse immer Vorrang.
quelle
Vielleicht würde ein Codebeispiel helfen, ich werde C # verwenden, aber Sie sollten in der Lage sein, mitzumachen.
Stellen wir uns vor, wir hätten eine Schnittstelle namens IPayable
Jetzt haben wir zwei konkrete Klassen, die diese Schnittstelle implementieren:
Stellen wir uns nun vor, wir hätten eine Sammlung verschiedener Konten. Dazu verwenden wir eine generische Liste vom Typ IPayable
Jetzt möchten wir 50,00 USD auf alle diese Konten zahlen:
Jetzt sehen Sie, wie unglaublich nützlich Schnittstellen sind.
Sie werden nur für instanziierte Objekte verwendet. Nicht für statische Klassen.
Wenn Sie die Zahlung statisch gemacht hätten, wäre es beim Durchlaufen der IPayable-Konten in AccountsToPay nicht möglich, herauszufinden, ob Pay on BusinessAcount oder CustomerAccount aufgerufen werden sollte.
quelle