Java 8 führt das Konzept der Standardmethoden ein. Betrachten Sie die folgende Schnittstelle mit einer Standardmethode:
%Vor%Und eine Klasse, die diese Schnittstelle implementiert:
%Vor% Ich habe eine Frage zur Lesbarkeit des folgenden Aufrufs in mayOrMayNotImplementThisMethod
:
Ich verstehe, dass der Grund für die explizite Angabe des Schnittstellennamens im obigen Aufruf darin besteht, Verwirrung zu vermeiden, falls mehrere von der Klasse implementierte Schnittstellen die gleiche Methode haben. Was ich nicht verstehe, ist die Bedeutung des Schlüsselworts super
in diesem Kontext. Wenn wir IDefaultMethod.super
sagen, worauf beziehen wir uns hier genau? Wäre IDefaultMethod.mayOrMayNotImplementThisMethod () besser lesbar als IDefaultMethod.super.mayOrMayNotImplementThisMethod ()? Wenn Sie das Schlüsselwort super entfernen, wird es besser lesbar, und zwar auf Kosten der Unterscheidung zwischen einem statischen oder nicht statischen Methodenaufruf.
Ich werde versuchen, zur Diskussion beizutragen, indem ich meinen eigenen Überlegungen darüber folge.
Sehen wir zuerst, wie dies mit einfachen Java-Klassen funktioniert:
%Vor% Wenn in diesem Fall die Methode foo
in einer Fred
Instanz aufgerufen wird, fragt sie nach der Implementierung der foo
Methode in ihrer Superklasse und führt diese aus.
Offensichtlich würde keiner dieser anderen funktionieren:
%Vor%Es gibt eine dritte Konfiguration, die wir tun könnten:
%Vor% Wenn wir foo
in einer Instanz von Fred
aufrufen, würde dieser Aufruf die Methode foo
in der umschließenden Instanz von Barney
aufrufen, da diese Instanz eine Bindung mit ihrer einschließenden Instanz hätte.
Zum Beispiel
%Vor% Also wird die Verwendung von Barney.this
hier verwendet, um zwischen Instanzen in einer inneren / äußeren Beziehung zu navigieren.
Versuchen wir nun, dieselben Ideen mit Interfaces zu wiederholen.
%Vor% Soweit ich das beurteilen kann, ist das genau dasselbe wie bei Klassen, nur weil in diesem Fall eine Schnittstelle von mehr als einer Schnittstelle erben kann, qualifizieren wir einfach das Schlüsselwort super
mit dem Namen der Schnittstelle, auf die wir in diesem Fall abzielen.
Die Bedeutung ist die gleiche, wir wollen die "Implementierung" der Methode foo
in der explizit benannten Superschnittstelle aufrufen.
Wie bei Klassen funktioniert Folgendes nicht:
%Vor% Also ist die logische Wahl hier Interface.super.method()
.
Eine Frage wäre hier, ob wir jemals einen Anwendungsfall wie Interface.this.method
bei der Verwendung von Schnittstellen haben.
Nicht wirklich, weil Interfaces einen statischen Kontext repräsentieren, daher gibt es niemals ein Konzept wie das von inneren Klassen zwischen Interfaces. Das ist also nie möglich.
%Vor% Grundsätzlich ist dies nicht möglich, weil der obige Code nicht bedeutet, dass eine Instanz von Fred
im Kontext einer Instanz von Barney
existieren müsste. Dies ist nur eine statische innere Schnittstelle und Instanzen davon können unabhängig von Instanzen der übergeordneten Schnittstelle existieren.
Also, deshalb wäre das keine gute Wahl.
Wie Sie also sehen, macht die Verwendung von super
irgendwie Sinn, oder zumindest hoffe ich, ich habe mich gut genug erklärt, um diese Idee zu vermitteln.
Dies ist einfach eine Erweiterung der Standardmethoden für den Zugriff auf Superklassenmitglieder (JLS 15.11) :
Die Form
T.super.Identifier
bezieht sich auf das FeldIdentifier
der lexikalisch umschließenden Instanz, dieT
entspricht, aber mit dieser Instanz als Instanz der Oberklasse vonT
.
Im Wesentlichen kann es Unklarheiten darüber geben, auf welches Element verwiesen wird, wenn eine Klasse mehr als einen Vorgänger hat (entweder aufgrund von Standardmethoden oder weil mehrere Superklassen in einer Hierarchie vorhanden sind). Das Schlüsselwort super
ist das Analogon von Outer.this
in einer inneren Klasse; Es bedeutet, dass Sie " this
" erhalten möchten, aber das Zeug, das ich im Körper dieser Oberklasse anstelle des Mitglieds innerhalb dieser Unterklasse sehen würde. "
super
bezieht sich auf eine Klasse oder Schnittstelle, von der Sie erben. Es bedeutet, dass Sie eine Methode aufrufen möchten, die die Tatsache ignoriert, dass sie außer Kraft gesetzt wurde.
Wenn Sie this
verwendet haben, würden Sie sich auf diese Klasse (oder eine Unterklasse) beziehen und somit eine unendliche Rekursion haben.
Java 8 Schnittstellen haben auch statische Methoden.
Wenn du sagst,
IDefaultMethod.mayOrMayNotImplementThisMethod ();
Dann ist es eine Möglichkeit, die statische Methode aufzurufen, was ebenfalls korrekt zu sein scheint, da sie ähnlich ist wie der Zugriff auf statische Member der Klasse.
Wenn für die Standardmethode 'super' nicht verwendet wird, haben sie möglicherweise 'this' verwendet, was keinen Sinn ergibt, da 'dies' zur Klasse gehört, in der wir Methoden aufrufen.
Meine Meinung ist, Sie haben Recht, da es keine gute Lesbarkeit bietet, aber es scheint, als ob es sich um Sprachdesign handelt.
Tags und Links java default-method