Warum versteckt eine innere Klassenmethode alle umschließenden Klassenmethoden mit demselben Namen?

9

In Anbetracht des folgenden Java-Codes:

%Vor%

Ich lese ein Buch, das mir sagt, dass Inner.method() beide Versionen von Enclosing.method() verbergen wird, was bedeutet, dass es ein Fehler ist, wenn ich method(aString) irgendwo in der Klasse Inner anrufe.

Warum ist die Sprache so gestaltet?

Aktualisieren :
Laut der Antwort von @Debosmit Ray ist dies mit shadowing verbunden. Ich habe die Dokumente gelesen und verstanden, was es ist.

Was mich immer noch verwirrt, ist, warum Method Shadowing auf Methodenname nicht Methodensignatur basiert?

    
free6om 18.03.2016, 06:35
quelle

4 Antworten

1

Hätten Sie das richtige Tag für Ihre Frage gefunden, hätten Sie das Konzept schon besser verstanden! Sehen Sie sich die Tag-Informationen zum Shadowing direkt auf SO an.

  

Bei der Computerprogrammierung tritt eine Spiegelung auf, wenn eine Variable deklariert wird   innerhalb eines bestimmten Bereichs (Entscheidungsblock, Methode oder innere Klasse) hat die   Derselbe Name wie eine Variable, die in einem äußeren Bereich deklariert ist. Dies kann dazu führen   Verwirrung, da es unklar sein kann, welche variable Nachnutzung der   beschatteter Variablenname beziehen sich auf, was von der Namensauflösung abhängt   Regeln der Sprache.

     

Eine der ersten Sprachen, die variable Shadowing eingeführt hat, war ALGOL,   welche zuerst Blöcke eingeführt hat, um Bereiche festzulegen. Es wurde auch   von vielen der abgeleiteten Programmiersprachen einschließlich erlaubt   C ++ und Java .

     

Die C # -Sprache bricht diese Tradition und erlaubt eine variable Beschattung   zwischen einer inneren und einer äußeren Klasse und zwischen einer Methode und ihrer   containing class, aber nicht zwischen einem if-block und seinem containing   Methode oder zwischen Case-Anweisungen in einem Switch-Block.

Wikipedia-Link (bietet jedoch nicht viel)

  

Warum ist die Sprache so gestaltet?

Lass mich dir eine echte Analogie geben, damit du sie verstehen kannst.

Denken Sie an ein Gebäude (1) mit einer Schaltfläche mit dem Namen Lichter einschalten (3). Wenn Sie diesen Knopf drücken, werden alle Lichter im Gebäude eingeschaltet. Denken Sie nun an eine Kabine (2) in diesem Gebäude. Es gibt eine kleine Lampe in dieser Kabine und eine ähnliche Taste mit dem Namen Licht einschalten . Jetzt, wenn Sie diesen Knopf drücken, was soll er tun - schalten Sie alle Lichter des Gebäudes ein, oder nur die Lampe in der Zelle ? Wahrscheinlich Letzteres. Obwohl beide Tasten denselben Namen (4) haben, verhalten sie sich je nach ihrer Stelle (5) anders.

Wenden Sie nun diese Analogie auf OOP an. Sieh dir die Wörter in kursiv noch einmal an und kombiniere sie!

  1. Gebäude - & gt; Umschließende Klasse
  2. Kabine - & gt; Innere Klasse
  3. Lichter einschalten - & gt; Methode
  4. Name - & gt; Methodenname / Unterschrift
  5. Ort - & gt; Bereich

Bitte beachten Sie, dass die Analogie viele andere Konzepte von OOP nicht berücksichtigt, aber ich denke, es könnte Ihnen helfen, den warum Teil Ihrer Frage zu verstehen.

Auf Update antworten:

  

Was mich immer noch verwirrt, ist, warum Method Shadowing auf Methodenname nicht Methodensignatur basiert?

Ihre Frage scheint nicht gültig zu sein. Sie werden das in Kürze verstehen.

Sie haben angegeben, dass das Shadowing nicht auf der Methodensignatur basiert. Wenn Sie damit meinen: "Wenn die innere Klassenmethode dieselbe Signatur wie die einschließende Klassenmethode hat, dann findet kein Shadowing statt" , dann liegen Sie falsch. Probieren Sie es aus, indem Sie innerhalb der inneren Klasse eine andere Methode wie void method(String str) erstellen und diese Methode innerhalb der inneren Klasse aufrufen. Sie werden sehen, dass es offensichtlich beschattet ist.

Und der Grund, warum Sie einen Fehler bekommen haben, als Sie method(aString) innerhalb der inneren Klasse aufgerufen haben, ist komplett etwas anderes - die Methode method(String str) existiert nicht einmal innerhalb des inneren Klassenbereichs.

Fühlen Sie sich frei, wenn Sie weitere Erläuterungen benötigen.

    
Sнаđошƒаӽ 18.03.2016, 07:14
quelle
2

Nicht-statische geschachtelte Klassen oder innere Klassen werden verwendet, um Klassen, die nur an einer Stelle verwendet werden, logisch zu gruppieren; Es macht den Code lesbarer und fördert Kapselung .

Aus [ Dokumente ],

  

Wenn eine Deklaration eines Typs (z. B. eine Elementvariable oder ein Parameter)   Name) in einem bestimmten Bereich (z. B. eine innere Klasse oder eine Methode)   Definition) hat den gleichen Namen wie eine andere Deklaration in der Einhüllenden   Geltungsbereich, dann überschattet die Deklaration die Deklaration des Einschließenden   Umfang.

Das Shadowing würde bedeuten, dass, wenn Sie eine Variable x in der äußeren Klasse und eine weitere Variable x in der inneren Klasse haben, die Änderung von x in der inneren Klasse keinen Einfluss auf hat x in der äußeren Klasse.

Ich mochte diese Frage und den Punkt, den Sie angesprochen haben, sehr. Hilft Ihnen meine Erklärung, zu verstehen?

    
Debosmit Ray 18.03.2016 07:03
quelle
1

Dies wird shadowing genannt.

Nach JLS 6.4.1

  

Einige Deklarationen können in einem Teil ihres Geltungsbereichs durch eine andere gleichnamige Deklaration beschattet werden. In diesem Fall kann ein einfacher Name nicht verwendet werden, um auf die deklarierte Entität zu verweisen.

Es ist praktisch, Schatten in der Programmiersprache zu haben. Zum Beispiel können Sie in Konstruktoren sowohl Parameter als auch Klassenfeldvariablen den gleichen Namen haben und this verwenden, um sie zu unterscheiden.

%Vor%

In einigen anderen Sprachen können Variablen durch Codeblöcke schattiert werden. In C ++ können Sie beispielsweise Code wie folgt schreiben:

%Vor%

Die Variable i innerhalb der Schleife unterscheidet sich von der externen i .

  

Warum ist die Sprache so gestaltet?

Wie Sie im Konstruktorbeispiel sehen können, können Variablen manchmal wirklich dasselbe bedeuten. Durch das Shadowing können Sie die gleichen Namen verwenden, ohne einen neuen Namen zu erstellen. Dies ist störend, da die Benennung einer Variablen nicht einfach ist.

Und im Loop-Beispiel , das in Java nicht unterstützt wird, aber ein großartiges Beispiel ist, um den Vorteil des Spiegelns zu zeigen , können Sie im Codeblock manchmal temporäre Variablen deklarieren, ohne andere Variablen außerhalb des zu ändern blockieren.

  

Warum basiert das Methoden-Shadowing auf Methodenname und Methodensignatur?

In JLS 15.12 gibt es eine Erklärung über Methodenaufruf.

Sie können sehen, dass der Compiler in Schritt 1 nach dem Bereich sucht, der diese Methode aufrufen kann. Am Ende hat es Enclosing.Inner gefunden.

Und in Schritt 2 überprüft der Compiler die Signatur der Methoden.

Daher wird der Compiler Enclosing.Inner.method() als einzige verfügbare Methode verwenden. Deshalb können Sie Enclosing.method(String str) nicht direkt aufrufen, obwohl sie eine andere Methodensignatur haben.

Wenn Sie Enclosing.method(String str) innerhalb der Klasse Inner aufrufen möchten, können Sie Folgendes tun:

%Vor%     
Nier 18.03.2016 09:14
quelle
0

Weil in diesem Scope, Method, Variables and constants Schatten über globale Methoden und Variablen gemacht werden ...

    
quelle

Tags und Links