Freigeben über


Shadowing in Visual Basic

Aktualisiert: November 2007

Wenn zwei Programmierelemente denselben Namen haben, kann eines das andere verdecken, bzw. Shadowing durchführen. In diesem Fall ist das Element, für das ein Shadowing durchgeführt wurde, für Verweise nicht verfügbar. Stattdessen löst der Visual Basic-Compiler den Verweis in das Shadowingelement auf, wenn der Code den Elementnamen verwendet.

Zweck

Hauptzweck des Shadowing ist es, die Definition von Klassenmembern zu schützen. Die Basisklasse wird vielleicht in einer Weise geändert, die ein Element mit dem gleichen Namen wie dem bereits definierten Namen zur Folge hat. In diesem Fall erzwingt der Shadows-Modifizierer, dass Verweise über die Klasse in den von Ihnen definierten Member aufgelöst werden und nicht in das neue Basisklassenelement.

Shadowingtypen

Für Shadowing zwischen zwei Elementen gibt es zwei Möglichkeiten. Das Shadowingelement kann innerhalb eines Unterbereichs des Bereichs deklariert werden, der das Element enthält, für das ein Shadowing durchgeführt wurde. In diesem Fall wird das Shadowing über den Gültigkeitsbereich erreicht. Es ist auch möglich, dass eine ableitende Klasse einen Member einer Basisklasse erneut definiert. In diesem Fall erfolgt das Shadowing durch Vererbung.

Shadowing über den Gültigkeitsbereich

Es ist möglich, dass Programmierelemente in demselben Modul, derselben Klasse oder derselben Struktur denselben Namen, aber unterschiedliche Gültigkeitsbereiche haben. Wenn zwei Elemente auf diese Weise deklariert wurden und der Code auf den gemeinsamen Namen verweist, führt das Element mit dem engeren Gültigkeitsbereich für das andere Element Shadowing durch. (Der Blockbereich ist der engste Gültigkeitsbereich.)

In einem Modul kann beispielsweise eine Public-Variable mit dem Namen temp definiert werden, während in einer Prozedur innerhalb des Moduls eine lokale Variable deklariert wird, die ebenfalls den Namen temp trägt. Verweise auf temp innerhalb der Prozedur greifen auf die lokale Variable zu, während Verweise auf temp außerhalb der Prozedur auf die Public-Variable zugreifen. In diesem Fall führt die Prozedurvariable temp ein Shadowing der Modulvariablen temp durch.

Die folgende Abbildung zeigt zwei Variablen mit dem Namen temp. Die lokale Variable temp führt ein Shadowing der Membervariablen temp durch, wenn innerhalb ihrer eigenen Prozedur p darauf zugegriffen wird. Allerdings umgeht das MyClass-Schlüsselwort das Shadowing und greift auf die Membervariable zu.

Shadowing über den Gültigkeitsbereich

Ein Beispiel für das Shadowing über den Gültigkeitsbereich finden Sie unter Gewusst wie: Ausblenden einer Variablen mit dem gleichen Namen wie die aktuelle Variable.

Shadowing durch Vererbung

Wenn eine abgeleitete Klasse ein von einer Basisklasse geerbtes Programmierelement neu definiert, führt das neu definierende Element für das Originalelement Shadowing durch. Für jeden deklarierten Elementtyp bzw. jede Gruppe überladener Elemente kann typunabhängig Shadowing durchgeführt werden. Beispielsweise kann eine Integer-Variable für eine Function -Prozedur Shadowing durchführen. Wenn eine Prozedur ein Shadowing einer anderen Prozedur durchführt, können Sie eine andere Parameterliste und einen anderen Rückgabetyp verwenden.

Die folgende Abbildung zeigt eine Basisklasse b und eine abgeleitete Klasse d, die von b erbt. Die Basisklasse definiert eine Prozedur mit dem Namen proc, und die abgeleitete Klasse führt ein Shadowing der Prozedur mit einer anderen Prozedur gleichen Namens durch. Die erste Call-Anweisung greift in der abgeleiteten Klasse auf die Shadowingprozedur proc zu. Allerdings umgeht das MyBase-Schlüsselwort das Shadowing und greift in der Basisklasse auf die Prozedur zu, für die ein Shadowing durchgeführt wurde.

Shadowing durch Vererbung

Ein Beispiel für das Shadowing durch Vererbung finden Sie unter Gewusst wie: Ausblenden einer Variablen mit dem gleichen Namen wie die aktuelle Variable und Gewusst wie: Ausblenden einer geerbten Variablen.

Shadowing und Zugriffsebene

Der Code, der die abgeleitete Klasse verwendet, kann nicht immer auf das Shadowingelement zugreifen. So könnte es zum Beispiel als Private deklariert sein. In einem solchen Fall erfolgt kein Shadowing, und der Compiler löst alle vorhandenen Verweise in das gleiche Element auf, als ob es kein Shadowing gäbe. Dieses Element ist das verwendbare Element, das die wenigsten Ableitungsschritte zurück von der Shadowingklasse liegt. Handelt es sich bei dem Element, für das ein Shadowing durchgeführt wurde, um eine Prozedur, wird in die nächstliegende Version mit dem gleichen Namen, der gleichen Parameterliste und dem gleichen Rückgabetyp aufgelöst, auf die zugegriffen werden kann.

Das folgende Beispiel zeigt eine Vererbungshierarchie mit drei Klassen. Jede Klasse definiert eine Sub-Prozedur display, und jede abgeleitete Klasse führt ein Shadowing der display-Prozedur in der entsprechenden Basisklasse durch.

Public Class firstClass
    Public Sub display()
        MsgBox("This is firstClass")
    End Sub
End Class
Public Class secondClass
    Inherits firstClass
    Private Shadows Sub display()
        MsgBox("This is secondClass")
    End Sub
End Class
Public Class thirdClass
    Inherits secondClass
    Public Shadows Sub display()
        MsgBox("This is thirdClass")
    End Sub
End Class
Module callDisplay
    Dim first As New firstClass
    Dim second As New secondClass
    Dim third As New thirdClass
    Public Sub callDisplayProcedures()
        ' The following statement displays "This is firstClass".
        first.display()
        ' The following statement displays "This is firstClass".
        second.display()
        ' The following statement displays "This is thirdClass".
        third.display()
    End Sub
End Module

Im vorhergehenden Beispiel führt die abgeleitete Klasse secondClass ein Shadowing von display mit einer Private-Prozedur durch. Wenn das callDisplay-Modul display in secondClass aufruft, befindet sich der aufrufende Code außerhalb von secondClass, sodass er nicht auf die private display-Prozedur zugreifen kann. Es erfolgt kein Shadowing, und der Compiler löst den Verweis in die display-Prozedur der Basisklasse auf.

Allerdings deklariert die weiter abgeleitete Klasse thirdClass die display-Prozedur als Public, sodass der Code in callDisplay darauf zugreifen kann.

Shadowing und Überschreiben

Shadowing ist nicht zu verwechseln mit dem Überschreiben. Beide Methoden werden verwendet, wenn eine abgeleitete Klasse von einer Basisklasse erbt und beide ein deklariertes Element durch ein anderes neu definieren. Es gibt jedoch klare Unterschiede zwischen den beiden Verfahren. Einen Vergleich finden Sie unter Unterschiede zwischen Shadowing und Überschreiben.

Shadowing und Überladen

Wenn Sie für ein und dasselbe Basisklassenelement mit mehr als einem Element in der abgeleiteten Klasse ein Shadowing durchführen, werden aus den Shadowingelementen überladene Versionen dieses Elements. Weitere Informationen finden Sie unter Prozedurüberladung.

Zugreifen auf ein Element, für das ein Shadowing durchgeführt wurde

Wenn auf ein Element über eine abgeleitete Klasse zugegriffen wird, erfolgt dies gewöhnlich über die aktuelle Instanz dieser abgeleiteten Klasse und durch die Qualifizierung des Elementnamens mit dem Me-Schlüsselwort. Wenn die abgeleitete Klasse für das Element der Basisklasse Shadowing durchführt, kann durch die Qualifizierung mithilfe des MyBase-Schlüsselworts auf das Element der Basisklasse zugegriffen werden.

Ein Beispiel für den Zugriff auf ein Element, für das ein Shadowing durchgeführt wurde, finden Sie unter Gewusst wie: Zugreifen auf eine Variable, die von einer abgeleiteten Klasse ausgeblendet wird.

Deklaration der Objektvariablen

Die Methode zum Erstellen der Objektvariablen kann sich auch darauf auswirken, ob die abgeleitete Klasse auf ein Shadowingelement oder auf das Element zugreift, für das ein Shadowing durchgeführt wurde. Im folgenden Beispiel werden zwei Objekte aus einer abgeleiteten Klasse erstellt. Ein Objekt wird allerdings als die Basisklasse und das andere als die abgeleitete Klasse deklariert.

Public Class baseCls
    ' The following statement declares the element that is to be shadowed.
    Public z As Integer = 100
End Class
Public Class dervCls
    Inherits baseCls
    ' The following statement declares the shadowing element.
    Public Shadows z As String = "*"
End Class
Public Class useClasses
    ' The following statement creates the object declared as the base class.
    Dim basObj As baseCls = New dervCls()
    ' Note that dervCls widens to its base class baseCls.
    ' The following statement creates the object declared as the derived class.
    Dim derObj As dervCls = New dervCls()
    Public Sub showZ() 
    ' The following statement outputs 100 (the shadowed element).
        MsgBox("Accessed through base class: " & basObj.z)
    ' The following statement outputs "*" (the shadowing element).
        MsgBox("Accessed through derived class: " & derObj.z)
    End Sub
End Class

Im vorhergehenden Beispiel wird die Variable basObj als Basisklasse deklariert. Die Zuweisung eines dervCls-Objekts generiert eine erweiternde Konvertierung und ist daher gültig. Die Basisklasse kann jedoch nicht auf die Shadowing-Version der Variablen z in der abgeleiteten Klasse zugreifen. Daher löst der Compiler basObj.z in den Wert der ursprünglichen Basisklasse auf.

Siehe auch

Konzepte

Gültigkeitsbereich in Visual Basic

Erweiternde und eingrenzende Konvertierungen

Referenz

Shadows

Overrides

Me

MyBase

Weitere Ressourcen

Verweise auf deklarierte Elemente