Schaduw in Visual Basic
Wanneer twee programmeerelementen dezelfde naam hebben, kan een van deze elementen de andere verbergen of schaduwen. In een dergelijke situatie is het schaduwelement niet ter referentie beschikbaar; In plaats daarvan, wanneer uw code gebruikmaakt van de elementnaam, wordt deze door de Visual Basic-compiler omgezet in het schaduwelement.
Doel
Het belangrijkste doel van schaduwen is om de definitie van uw klasleden te beschermen. De basisklasse kan een wijziging ondergaan waarmee een element wordt gemaakt met dezelfde naam als een element dat u al hebt gedefinieerd. Als dit gebeurt, dwingt de Shadows
wijzigingsfunctie af dat verwijzingen via uw klasse worden omgezet naar het lid dat u hebt gedefinieerd, in plaats van naar het nieuwe basisklasse-element.
Typen schaduw
Een element kan op twee verschillende manieren een ander element schaduwen. Het schaduwelement kan worden gedeclareerd in een subregio van het gebied met het schaduwelement, in welk geval de schaduw wordt bereikt via het bereik. Of een afleidende klasse kan een lid van een basisklasse opnieuw definiëren, in welk geval de schaduw wordt uitgevoerd via overname.
Schaduw door bereik
Het is mogelijk dat programmeerelementen in dezelfde module, klasse of structuur dezelfde naam hebben, maar een ander bereik. Wanneer twee elementen op deze manier worden gedeclareerd en de code verwijst naar de naam die ze delen, wordt het element met de smallere bereikschaduwen het andere element (blokbereik is het smalste).
Een module kan bijvoorbeeld een variabele met de Public
naam temp
definiëren en een procedure in de module kan ook een lokale variabele met de naam temp
declareren. Verwijzingen naar temp
vanuit de procedure hebben toegang tot de lokale variabele, terwijl verwijzingen naar temp
van buiten de procedure toegang hebben tot de Public
variabele. In dit geval schaduwt de procedurevariabele de modulevariabele temp
temp
.
In de volgende afbeelding ziet u twee variabelen, beide benoemd temp
. De lokale variabele schaduwt de lidvariabele temp
temp
wanneer deze wordt geopend vanuit een eigen procedure p
. Het MyClass
trefwoord omzeilt echter de schaduw en heeft toegang tot de lidvariabele.
Zie Een variabele verbergen met dezelfde naam als uw variabele voor een voorbeeld van schaduw door het bereik.
Schaduw door overname
Als een afgeleide klasse een programmeerelement dat is overgenomen van een basisklasse opnieuw definieert, wordt het oorspronkelijke element opnieuw gedefinieerd. U kunt elk type gedeclareerd element of een set overbelaste elementen schaduwen, met elk ander type. Een variabele kan bijvoorbeeld Integer
een Function
procedure schaduwen. Als u een procedure met een andere procedure schaduwt, kunt u een andere parameterlijst en een ander retourtype gebruiken.
In de volgende afbeelding ziet u een basisklasse b
en een afgeleide klasse d
die wordt overgenomen van b
. De basisklasse definieert een procedure met de naam proc
en de afgeleide klasse schaduwt deze met een andere procedure met dezelfde naam. De eerste Call
instructie heeft toegang tot de schaduw in proc
de afgeleide klasse. Het MyBase
trefwoord omzeilt echter de schaduw en heeft toegang tot de schaduwprocedure in de basisklasse.
Zie Procedure voor een voorbeeld van schaduwen via overname : Een variabele verbergen met dezelfde naam als uw variabele en instructies: Een overgenomen variabele verbergen.
Schaduw- en toegangsniveau
Het schaduwelement is niet altijd toegankelijk vanuit de code met behulp van de afgeleide klasse. Het kan bijvoorbeeld worden gedeclareerd Private
. In dat geval wordt schaduwen verslagen en lost de compiler elke verwijzing op naar hetzelfde element dat het zou hebben als er geen schaduw was geweest. Dit element is het toegankelijke element dat de slechtste derivationale stappen achteruit van de schaduwklasse afstapt. Als het schaduwelement een procedure is, is de oplossing naar de dichtstbijzijnde toegankelijke versie met dezelfde naam, parameterlijst en retourtype.
In het volgende voorbeeld ziet u een overnamehiërarchie van drie klassen. Elke klasse definieert een Sub
procedure display
en elke afgeleide klasse schaduwt de procedure in de display
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
In het voorgaande voorbeeld worden de afgeleide klasseschaduwen secondClass
display
met een Private
procedure. Wanneer module callDisplay
wordt aangeroepen display
secondClass
, bevindt de aanroepende code zich buiten secondClass
en heeft deze dus geen toegang tot de privéprocedure display
. Schaduw wordt verslagen en de compiler lost de verwijzing naar de basisklasseprocedure display
op.
De verdere afgeleide klasse thirdClass
declareert display
echter als Public
, zodat de code er callDisplay
toegang toe heeft.
Schaduw en overschrijven
Verwar schaduw niet met overschrijven. Beide worden gebruikt wanneer een afgeleide klasse wordt overgenomen van een basisklasse en beide het ene gedeclareerde element opnieuw definiëren met een andere. Maar er zijn aanzienlijke verschillen tussen de twee. Zie Verschillen tussen schaduw en overschrijven voor een vergelijking.
Schaduw en overbelasting
Als u hetzelfde basisklasseelement schaduwt met meer dan één element in uw afgeleide klasse, worden de schaduwelementen overbelaste versies van dat element. Zie Procedure overloading voor meer informatie.
Toegang tot een schaduwelement
Wanneer u toegang krijgt tot een element van een afgeleide klasse, doet u dit normaal gesproken via het huidige exemplaar van die afgeleide klasse door de elementnaam te kwalificeren met het Me
trefwoord. Als uw afgeleide klasse het element in de basisklasse schaduwt, hebt u toegang tot het basisklasse-element door dit te kwalificeren met het MyBase
trefwoord.
Zie Procedure voor een voorbeeld van het openen van een schaduwelement : Toegang krijgen tot een variabele die is verborgen door een afgeleide klasse.
Declaratie van de objectvariabele
Hoe u de objectvariabele maakt, kan ook van invloed zijn op het feit of de afgeleide klasse toegang heeft tot een schaduwelement of het schaduwelement. In het volgende voorbeeld worden twee objecten gemaakt op basis van een afgeleide klasse, maar één object wordt gedeclareerd als de basisklasse en de andere als de afgeleide klasse.
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
In het voorgaande voorbeeld wordt de variabele basObj
gedeclareerd als de basisklasse. Het toewijzen van een dervCls
object aan het object vormt een widening conversie en is daarom geldig. De basisklasse heeft echter geen toegang tot de schaduwversie van de variabele z
in de afgeleide klasse, dus de compiler wordt omgezet basObj.z
in de oorspronkelijke basisklassewaarde.