Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Wenn zwei Programmierelemente denselben Namen aufweisen, kann eines davon die andere ausblenden oder schatten. In einer solchen Situation steht das schattierte Element nicht zur Referenz zur Verfügung; Wenn ihr Code den Elementnamen verwendet, löst der Visual Basic-Compiler ihn stattdessen in das Schattenelement auf.
Zweck
Der Hauptzweck von Shadowing besteht darin, die Definition Ihrer Klassenmember zu schützen. Die Basisklasse kann sich einer Änderung unterziehen, durch die ein Element mit demselben Namen erstellt wird, den Sie bereits definiert haben. Wenn dies der Fall ist, zwingt der Shadows
Modifizierer dazu, dass Verweise durch Ihre Klasse auf das von Ihnen definierte Mitglied aufgelöst werden, anstatt auf das neue Basisklassenelement.
Arten der Schattenbildung
Ein Element kann ein anderes Element auf zwei verschiedene Arten schatten. Das Element, das das Shadowing durchführt, kann in einem Unterbereich des Bereichs deklariert werden, der das dem Shadowing unterzogene Element enthält. In diesem Fall wird das Shadowing über den Gültigkeitsbereich (scope) durchgeführt. Oder eine ableitende Klasse kann ein Element einer Basisklasse neu definieren, in diesem Fall erfolgt die Schattenerstellung durch Vererbung.
Shadowing über den Gültigkeitsbereich
Es ist möglich, dass Programmierelemente in demselben Modul, derselben Klasse oder Struktur denselben Namen, aber einen anderen Bereich aufweisen. Wenn zwei Elemente auf diese Weise deklariert werden und sich der Code auf den Namen bezieht, den sie teilen, überschattet das Element mit dem schmaleren Gültigkeitsbereich das andere Element (Blockbereich ist der schmalste).
Beispielsweise kann ein Modul eine Public
Variable namens temp
definieren, und eine Prozedur innerhalb des Moduls kann eine lokale Variable auch mit dem Namen temp
deklarieren.
temp
Verweise von innerhalb der Prozedur greifen auf die lokale Variable zu, während Verweise temp
von außerhalb der Prozedur auf die Public
Variable zugreifen. In diesem Fall schattiert die Prozedurvariable temp
die Modulvariable temp
.
Die folgende Abbildung zeigt zwei Variablen, die beide benannt sind temp
. Die lokale Variable temp
führt ein Shadowing durchführen der Membervariablen temp
durch, wenn aus ihrer eigenen Prozedur p
auf sie zugegriffen wird. Das Schlüsselwort MyClass
umgeht jedoch das Shadowing und greift auf die Membervariable zu.
Ein Beispiel für das Shadowing über den Gültigkeitsbereich finden Sie unter Gewusst wie: Ausblenden einer Variablen mit demselben Namen wie Ihre Variable.
Shadowing durch Vererbung
Wenn eine abgeleitete Klasse ein von einer Basisklasse geerbtes Programmierelement neu definiert, schattiert das neu definierte Element das ursprüngliche Element. Sie können jede Art deklarierter Elemente oder überladene Elemente mit jedem anderen Typ abschatten. Beispielsweise kann eine Integer
Variable eine Function
Prozedur schatten. Wenn Sie eine Prozedur mit einer anderen Prozedur abschatten, 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 namens proc
, und die abgeleiteten Klassen schatten sie mit einer anderen Prozedur mit demselben Namen. Die erste Call
-Anweisung greift auf die das Shadowing durchführende proc
der abgeleiteten Klasse zu. Das Schlüsselwort MyBase
umgeht jedoch das Shadowing und greift auf die dem Shadowing unterzogene Prozedur in der Basisklasse zu.
Ein Beispiel für das Shadowing durch Vererbung finden Sie unter Gewusst wie: Ausblenden einer Variablen mit demselben Namen wie Ihre Variable und Gewusst wie: Ausblenden einer geerbten Variablen.
Shadowing und Zugriffsebene
Auf das Schattenelement kann nicht immer über den Code mithilfe der abgeleiteten Klasse zugegriffen werden. Beispielsweise kann es deklariert Private
werden. In einem solchen Fall wird das Shadowing außer Kraft gesetzt, und der Compiler löst jeden Verweis auf dasselbe Element auf, das er verwendet hätte, wenn kein Shadowing vorgelegen hätte. Bei diesem Element handelt es sich um das zugängliche Element, das die wenigsten ableitenden Schritte rückwärts von der das Shadowing durchführenden Klasse entfernt ist. Wenn das schattierte Element eine Funktion ist, wird die Auflösung auf die nächstgelegene zugängliche Version mit demselben Namen, derselben Parameterliste und demselben Rückgabetyp vorgenommen.
Das folgende Beispiel zeigt eine Vererbungshierarchie von drei Klassen. Jede Klasse definiert eine Sub
Prozedur, und jede abgeleitete Klasse schattiert die display
Prozedur display
in ihrer Basisklasse.
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 vorherigen Beispiel überschattet die abgeleitete Klasse secondClass
display
mit einer Private
-Prozedur. Wenn das Modul callDisplay
im display
secondClass
aufruft, befindet sich der aufrufende Code außerhalb von secondClass
und kann daher nicht auf die private display
Prozedur zugreifen. Das Überschatten wird aufgehoben, und der Compiler löst den Verweis auf die Prozedur der Basisklasse display
auf.
Die weiter abgeleitete Klasse thirdClass
deklariert display
als Public
, sodass der Code in callDisplay
darauf zugreifen kann.
Shadowing und Überschreiben
Verwechseln Sie Shadowing nicht mit Überschreiben. Beide werden verwendet, wenn eine abgeleitete Klasse von einer Basisklasse erbt und beide ein deklariertes Element mit einem anderen neu definieren. Aber es gibt erhebliche Unterschiede zwischen den beiden. Einen Vergleich finden Sie unter Unterschiede zwischen Shadowing und Überschreiben.
Shadowing und Überladen
Wenn Sie das gleiche Basisklassenelement mit mehreren Elementen in der abgeleiteten Klasse schattenn, werden die Schattenelemente zu überladenen Versionen dieses Elements. Weitere Informationen finden Sie unter Prozedurüberladung.
Zugreifen auf ein schatteniertes Element
Wenn Sie auf ein Element aus einer abgeleiteten Klasse zugreifen, erfolgt dies normalerweise über die aktuelle Instanz dieser abgeleiteten Klasse, indem Sie den Elementnamen mit dem Me
Schlüsselwort qualifizieren. Wenn ihre abgeleitete Klasse das Element in der Basisklasse schattiert, können Sie auf das Basisklassenelement zugreifen, indem Sie es mit dem MyBase
Schlüsselwort qualifizieren.
Ein Beispiel für den Zugriff auf ein schattiertes Element finden Sie unter How to: Access a Variable Hidden by a Derived Class.
Deklaration der Objektvariable
Wie Sie die Objektvariable erstellen, kann sich auch darauf auswirken, ob die abgeleitete Klasse auf ein Schattenelement oder auf das schattierte Element zugreift. Im folgenden Beispiel werden zwei Objekte aus einer abgeleiteten Klasse erstellt, aber ein Objekt wird als Basisklasse und das andere als 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 vorherigen Beispiel wird die Variable basObj
als Basisklasse deklariert. Das Zuweisen eines dervCls
-Objekts zu dieser Variablen stellt eine erweiternde Konvertierung dar und ist daher gültig. Die Basisklasse kann jedoch nicht auf die Schattenversion der Variablen z
in der abgeleiteten Klasse zugreifen, sodass der Compiler basObj.z
auf den ursprünglichen Wert der Basisklasse auflöst.