Delen via


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 tempdefiniëren en een procedure in de module kan ook een lokale variabele met de naam tempdeclareren. 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.

Graphic that shows shadowing through scope.

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 procen 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.

Graphic diagram of shadowing through inheritance

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 displayen 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.

Zie ook