Dela via


Skuggning i Visual Basic

När två programmeringselement har samma namn kan den ena dölja eller skugga den andra. I en sådan situation är det skuggade elementet inte tillgängligt som referens. I stället, när koden använder elementnamnet, löser Visual Basic-kompilatorn det till skuggelementet.

Syfte

Huvudsyftet med skuggning är att skydda definitionen av dina klassmedlemmar. Basklassen kan genomgå en ändring som skapar ett element med samma namn som ett som du redan har definierat. Om detta händer Shadows tvingar modifieraren referenser via klassen att matchas till den medlem som du definierade, i stället för till det nya basklasselementet.

Typer av skuggning

Ett element kan skugga ett annat element på två olika sätt. Skuggningselementet kan deklareras i en underregion i regionen som innehåller det skuggade elementet, i vilket fall skuggningen utförs via omfånget. Eller så kan en härledande klass omdefiniera en medlem i en basklass, i vilket fall skuggningen görs genom arv.

Skuggning genom omfång

Det är möjligt att programmeringselement i samma modul, klass eller struktur har samma namn men ett annat omfång. När två element deklareras på det här sättet och koden refererar till namnet de delar skuggar elementet med det smalare omfånget det andra elementet (blockomfånget är det smalaste).

En modul kan till exempel definiera en Public variabel med namnet temp, och en procedur i modulen kan deklarera en lokal variabel med namnet temp. Referenser till temp inifrån proceduren kommer åt den lokala variabeln, medan referenser till temp utanför proceduren kommer åt variabeln Public . I det här fallet skuggar procedurvariabeln temp modulvariabeln temp.

Följande bild visar två variabler, båda med namnet temp. Den lokala variabeln temp skuggar medlemsvariabeln temp när den nås från sin egen procedur p. Nyckelordet MyClass kringgår dock skuggningen och kommer åt medlemsvariabeln.

Graphic that shows shadowing through scope.

Ett exempel på skuggning genom omfång finns i How to: Hide a Variable with the Same Name as Your Variable (Så här döljer du en variabel med samma namn som din variabel).

Skuggning genom arv

Om en härledd klass omdefinierar ett programmeringselement som ärvts från en basklass skuggar det omdefinierande elementet det ursprungliga elementet. Du kan skugga alla typer av deklarerade element eller uppsättningar överlagrade element med någon annan typ. En variabel kan till exempel Integer skugga en Function procedur. Om du skuggar en procedur med en annan procedur kan du använda en annan parameterlista och en annan returtyp.

Följande bild visar en basklass b och en härledd klass d som ärver från b. Basklassen definierar en procedur med namnet proc, och den härledda klassen skuggar den med en annan procedur med samma namn. Den första Call instruktionen kommer åt skuggningen proc i den härledda klassen. Nyckelordet MyBase kringgår dock skuggningen och kommer åt den skuggade proceduren i basklassen.

Graphic diagram of shadowing through inheritance

Ett exempel på skuggning genom arv finns i How to: Hide a Variable with the Same Name as Your Variable and How to: Hide an Inherited Variable (Så här döljer du en variabel med samma namn som din variabel och gör så här: Dölj en ärvd variabel).

Skuggning och åtkomstnivå

Skuggelementet är inte alltid tillgängligt från koden med hjälp av den härledda klassen. Den kan till exempel deklareras Private. I sådana fall besegras skuggning och kompilatorn löser alla referenser till samma element som den skulle ha om det inte hade förekommit någon skuggning. Det här elementet är det tillgängliga elementet de minsta härledningsstegen bakåt från skuggningsklassen. Om det skuggade elementet är en procedur är lösningen den närmast tillgängliga versionen med samma namn, parameterlista och returtyp.

I följande exempel visas en arvshierarki med tre klasser. Varje klass definierar en Sub procedur displayoch varje härledd klass skuggar proceduren i basklassen display .

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  

I föregående exempel skuggar display den härledda klassen secondClass med en Private procedur. När modulen callDisplay anropar display i secondClassär den anropande koden utanför secondClass och kan därför inte komma åt den privata display proceduren. Skuggning har besegrats och kompilatorn löser referensen till basklassproceduren display .

Den ytterligare härledda klassen thirdClass deklarerar display dock som Public, så att koden i callDisplay kan komma åt den.

Skuggning och åsidosättande

Blanda inte ihop skuggning med åsidosättande. Båda används när en härledd klass ärver från en basklass och båda omdefinierar ett deklarerat element med ett annat. Men det finns betydande skillnader mellan de två. En jämförelse finns i Skillnader mellan skuggning och åsidosättande.

Skuggning och överlagring

Om du skuggar samma basklasselement med mer än ett element i din härledda klass blir skuggelementen överbelastade versioner av det elementet. Mer information finns i Överlagring av procedurer.

Komma åt ett skuggat element

När du kommer åt ett element från en härledd klass gör du normalt det via den aktuella instansen av den härledda klassen genom att kvalificera elementnamnet med nyckelordet Me . Om din härledda klass skuggar elementet i basklassen kan du komma åt basklasselementet genom att kvalificera det med nyckelordet MyBase .

Ett exempel på hur du kommer åt ett skuggat element finns i Så här använder du en variabel som är dold av en härledd klass.

Deklaration av objektvariabeln

Hur du skapar objektvariabeln kan också påverka om den härledda klassen kommer åt ett skuggelement eller det skuggade elementet. I följande exempel skapas två objekt från en härledd klass, men ett objekt deklareras som basklassen och det andra som den härledda klassen.

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  

I föregående exempel deklareras variabeln basObj som basklass. Att tilldela ett dervCls objekt till det utgör en bredare konvertering och är därför giltig. Basklassen kan dock inte komma åt skuggningsversionen av variabeln z i den härledda klassen, så kompilatorn matchar basObj.z det ursprungliga basklassvärdet.

Se även