Verwendung von Membervariablen mit Interfaces und anonymen Implementierungen

8

Bitte überprüfen Sie den folgenden Java-Code:

%Vor%

Wie Sie sehen, habe ich anonym eine Schnittstelle erstellt. Wenn ich direkt auf die Interface-Variable zugreife, wird "Old value" angezeigt.

t.meth (). s = & gt; "Alter Wert"

Der Zugriff auf sie über die Methode getVal () gibt die richtigen Werte zurück,

t.meth (). getVal () = & gt; "String-Implementierung"

Ich verstehe nicht, wie dieser Code funktioniert, kann mir das jemand erklären?

    
sprabhakaran 06.06.2013, 06:05
quelle

4 Antworten

7

Die in der Schnittstelle deklarierte Variable s ist völlig separat von der Variablen s , die Sie in Ihrer anonymen inneren Klasse deklariert haben.

Interface-Variablen sind eigentlich nur Konstanten - sie sind nicht Teil der API, die jede Implementierung bereitstellen muss. Insbesondere sind sie implizit statisch und endgültig.

Aus dem JLS Abschnitt 9.3 :

  

Jede Felddeklaration im Rumpf einer Schnittstelle ist implizit public, static und final. Es ist zulässig, einen oder alle dieser Modifikatoren für solche Felder redundant anzugeben.

Die Tatsache, dass Sie über eine Implementierungsinstanz auf das Feld zugegriffen haben, ist irrelevant - dieser Code:

%Vor%

ist effektiv:

%Vor%

Ich würde Sie dringend ermutigen, die Verwendung von Variablen in Schnittstellen außer für echte Konstanten zu vermeiden ... und selbst dann nur dort, wo es wirklich Sinn macht. Es ist nicht klar, was Sie erreichen wollen, aber ein Feld in einer Schnittstelle zu deklarieren, ist kein guter Weg, IMO weiterzugeben.

    
Jon Skeet 06.06.2013, 06:13
quelle
3

Es gibt nichts wie variable-overriding like method overriding in Java. Benennen Sie einen neuen Typ für subclass , dann erhalten Sie "String Implementation" , wenn Sie über den Unterklassenreferenztyp darauf zugreifen.

Zugriffsberechtigung protected bedeutet nur, dass wir auf die Variable in einer Unterklasse zugreifen können, aber nicht, dass sie überschrieben werden kann.

Selbst wenn Sie normale class anstelle von interface verwenden, funktioniert das nicht. Wenn Sie mit dem Klassen-Typ super referenzieren, erhalten Sie nur die Variablen instance von super type usw. Dieses Beispiel veranschaulicht den ersten Fall: Beispiel:

%Vor%

Dieses Beispiel veranschaulicht den zweiten Fall:  Es druckt "String Implementation"

%Vor%     
pinkpanther 06.06.2013 06:13
quelle
1
%Vor%

Sie haben die Referenz des Interface-Typs, deshalb bezieht sie sich direkt auf die Schnittstelle und Sie erhalten "Alter Wert"

%Vor%

Wenn Sie die Methode getVal () aufrufen, beziehen Sie sich auf die tatsächliche Implementierung dieser Methode und deshalb wird getVal der tatsächlichen Implementierung aufgerufen. Dies bedeutet aktuelle Instanz mit dem folgenden Wert:

%Vor%     
shevchyk 06.06.2013 06:13
quelle
1

In einer Schnittstelle deklarierte Felder sind Konstanten.

Also beim Schreiben

%Vor%

Sie deklarieren eine Konstante s. Deshalb druckt t.meth().s Old value

t.meth().getVal() druckt den Inhalt des Feldes s Ihrer anonymen Klasse.

    
Guillaume Darmont 06.06.2013 06:14
quelle

Tags und Links