Worauf bezieht sich Java "this" eigentlich in einer Vererbungssituation?

8

Warum erzeugt der folgende Java-Code:

%Vor%

Der fragliche Code lautet:

%Vor%

Es wurde keine Instanz von SuperClass erstellt, nicht wahr? Nicht nur, dass Java nach der Methode sucht, die von SuperClass aufgerufen werden kann, es weiß sogar irgendwie, dass a = 10 !

Betrachten wir einen ähnlichen Python-Code:

%Vor%

Es funktioniert wie ich es erwarte:

%Vor%

Die einzige Erklärung, die meine Kollegen (Python, die Java-Leute nicht mögen) vorgebracht haben, ist: "Python ist keine echte OOP-Sprache". Nicht sehr überzeugend.

Update: private void another_print() ist mein Fehler, ich hätte protected verwenden sollen.

    
Kirill 12.01.2016, 22:12
quelle

4 Antworten

8

Es ist die Reihenfolge, in der der Konstruktor in Java aufruft.
In SubClass ruft der Konstruktor implizit den Standardkonstruktor von c ( SuperClass ) auf, wenn Sie public SuperClass() instanziieren (dies muss geschehen). Dann wird a in SuperClass auf 10 gesetzt.

Nachdem wir nun mit dem Konstruktor SuperClass fertig sind, kehren wir zum Konstruktor von SubClass zurück, der a = 20 zuweist. Aber Felder sind in Java nicht überschreibbar, also ist a in SuperClass immer noch 10.

Danach ist es ziemlich offensichtlich, wir nennen c.print() , was print von SubClass aufruft, was die print von SuperClass (by super.print() ) aufruft, die a ausgibt, was as ist Sie erinnern sich 10. Dann another_print (was nicht überschrieben wird, da es private ist) druckt nur superclass und wir sind fertig.

    
Idos 12.01.2016, 22:16
quelle
8

Im Print der Unterklasse rufen Sie einfach die Druckmethode der Superklasse auf. Es druckt natürlich das a aus der Superklasse.

Sie haben hier zwei separate a Felder. Felder sind nicht zu überschreiben, nur Methoden sind. Die Superklasse hat ein a -Feld und Sie haben ein weiteres a -Feld in der Unterklasse.

Wenn eine andere Sprache ein anderes Ergebnis produziert, ist das keine große Überraschung. Ich bin mir auch nicht sicher, ob Ihr Python-Code logisch äquivalent zu Ihrem Java-Code ist.

    
peter.petrov 12.01.2016 22:16
quelle
2

Mein Kommentar erklärte den Grund, warum Ihr Code wahrscheinlich nicht wie erwartet funktioniert. Im Folgenden ist Code geschrieben, wie Sie wahrscheinlich erwartet haben, dass es funktioniert. Beachten Sie die Kommentare im Code.

%Vor%

Dies wird gedruckt

%Vor%     
George Mulligan 12.01.2016 22:23
quelle
0

Ich habe meinen leicht korrigierten Code ausgepackt und herausgefunden, dass:

  1. this ist eine Instanz von SubClass
  2. Im Gegensatz zu Python ist Java mit mehr als einer Variablen mit demselben Namen in Ordnung (wie peter.petrov in seiner Antwort , aber ich habe es nicht sofort verstanden)
  3. Eines der a s stammt von SubClass und das zweite stammt von SuperClass (als impliziter Aufruf des Konstruktors der Superklasse, wiederum im Gegensatz zu Python)
  4. this.a hat einen anderen Wert in test_super() und test_sub() und das ist der Zauber, denn this ist ein SubClass und die Java-Dokumentation lautet:
  

this ist eine Referenz auf das aktuelle Objekt - das Objekt, dessen Methode oder Konstruktor aufgerufen wird

Ich denke, ich kann mit der Tatsache leben, dass this alle Variablen aus dem gesamten Abhängigkeitsbaum haben wird und Java je nach Kontext auswählen wird, welches verwendet wird.

    
Kirill 13.01.2016 10:01
quelle