Ja, Sie können innerhalb einer Java-Schnittstelle sowohl eine verschachtelte als auch eine innere Klasse erstellen (beachten Sie, dass es entgegen der landläufigen Meinung keine " statische innere Klasse " gibt: Dies macht einfach keinen Sinn, es gibt nichts "Inneres" und "Nein". outter "Klasse, wenn eine verschachtelte Klasse statisch ist, also nicht" statisch inner "sein kann).
Wie auch immer, das Folgende kompiliert gut:
public interface A {
class B {
}
}
Ich habe gesehen, dass es verwendet wurde, um eine Art "Vertragsprüfer" direkt in die Schnittstellendefinition einzufügen (nun, in der in der Schnittstelle verschachtelten Klasse, die statische Methoden haben kann, im Gegensatz zur Schnittstelle selbst, die dies nicht kann). Sieht so aus, wenn ich mich richtig erinnere.
public interface A {
static class B {
public static boolean verifyState( A a ) {
return (true if object implementing class A looks to be in a valid state)
}
}
}
Beachten Sie, dass ich die Nützlichkeit einer solchen Sache nicht kommentiere, sondern nur Ihre Frage beantworte: Sie kann durchgeführt werden, und dies ist eine Art von Verwendung, die ich gesehen habe.
Jetzt werde ich die Nützlichkeit eines solchen Konstrukts nicht kommentieren und habe gesehen: Ich habe es gesehen, aber es ist kein sehr verbreitetes Konstrukt.
200KLOC-Codebasis hier, wo dies genau null Mal geschieht (aber dann haben wir viele andere Dinge, die wir als schlechte Praktiken betrachten, die genau null Zeit passieren, die andere Leute als völlig normal empfinden würden, also ...).
interface
s keine inneren Klassen haben. Sie können denstatic
Modifikator einerinterface
verschachtelten Klasse weglassen, aber es ist dennoch eine verschachtelte Klasse, keine innere Klasse.B
Klasse eine statisch verschachtelte Klasse und keine innere Klasse. Schnittstellen werden speziell behandelt. Ich konnte dies online nicht erwähnen, außer in der Spezifikation selbst: "Eine Mitgliedsklasse einer Schnittstelle ist implizit statisch und wird daher niemals als innere Klasse betrachtet." docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3Ja, wir können Klassen in Schnittstellen haben. Ein Anwendungsbeispiel könnte sein
Hier hat der Code zwei verschachtelte Klassen, die zum Einkapseln von Informationen über Ereignisobjekte dienen, die später in Methodendefinitionen wie getKeyEvents () verwendet werden. Wenn sie sich in der Eingabeschnittstelle befinden, wird der Zusammenhalt verbessert.
quelle
Eine gültige Verwendung, IMHO, definiert Objekte, die von den einschließenden Schnittstellenmethoden empfangen oder zurückgegeben werden. Typischerweise Datenhaltestrukturen. Wenn das Objekt nur für diese Schnittstelle verwendet wird, haben Sie die Dinge auf diese Weise zusammenhängender.
Zum Beispiel:
Aber trotzdem ... es ist nur eine Frage des Geschmacks.
quelle
Zitat aus der Java 7-Spezifikation :
Es ist NICHT möglich, nicht statische Klassen innerhalb einer Java-Schnittstelle zu deklarieren, was für mich sinnvoll ist.
quelle
Ein interessanter Anwendungsfall besteht darin, eine Art Standardimplementierung für Schnittstellenmethoden über eine innere Klasse bereitzustellen, wie hier beschrieben: https://stackoverflow.com/a/3442218/454667 (um das Problem der Vererbung einzelner Klassen zu überwinden).
quelle
Es ist sicherlich möglich, und ein Fall, in dem ich es nützlich fand, ist, wenn eine Schnittstelle benutzerdefinierte Ausnahmen auslösen muss. Sie behalten die Ausnahmen mit der zugehörigen Schnittstelle bei, was meiner Meinung nach oft ordentlicher ist, als Ihren Quellbaum mit Haufen trivialer Ausnahmedateien zu verunreinigen.
quelle
Ja, es ist möglich, statische Klassendefinitionen in einer Schnittstelle zu haben, aber der vielleicht nützlichste Aspekt dieser Funktion ist die Verwendung von Aufzählungstypen (bei denen es sich um spezielle statische Klassen handelt). Zum Beispiel können Sie so etwas haben:
quelle
Was @Bachi erwähnt, ähnelt den Merkmalen in Scala und wird tatsächlich mithilfe einer verschachtelten Klasse in einer Schnittstelle implementiert. Dies kann in Java simuliert werden. Siehe auch Java-Merkmale oder Mixins-Muster?
quelle
Wenn Sie komplexere Konstruktionen wie unterschiedliche Implementierungsverhalten wünschen, sollten Sie Folgendes berücksichtigen:
Dies ist Ihre Schnittstelle und dies wird der Implementierer sein:
Kann einige statische Implementierungen bereitstellen, aber das wird nicht verwirrend sein, ich weiß es nicht.
quelle
Ich habe eine Verwendung für diese Art von Konstrukt gefunden.
Sie haben Zugriff auf alle gruppierten Konstanten. Der Name der Klasse fungiert in diesem Fall als Namespace.
quelle
Sie können auch statische "Helper" -Klassen für allgemeine Funktionen für die Objekte erstellen, die diese Schnittstelle implementieren:
quelle
Ich brauche gerade einen. Ich habe eine Schnittstelle, über die es praktisch wäre, eine eindeutige Klasse aus mehreren Methoden zurückzugeben. Diese Klasse ist nur als Container für Antworten von Methoden dieser Schnittstelle sinnvoll.
Daher wäre es praktisch, eine statische verschachtelte Klassendefinition zu haben, die nur dieser Schnittstelle zugeordnet ist, da diese Schnittstelle der einzige Ort sein sollte, an dem diese Ergebniscontainerklasse jemals erstellt wird.
quelle
Zum Beispiel Merkmale (smth wie Schnittstelle mit implementierten Methoden) in Groovy. Sie werden zu einer Schnittstelle kompiliert, die eine innere Klasse enthält, in der alle Methoden implementiert sind.
quelle