Sdílet prostřednictvím


Stínování v jazyce Visual Basic

Když dva programovací prvky sdílejí stejný název, jeden z nich může skrýt nebo zastínit ten druhý. V takové situaci není stínovaný prvek k dispozici pro referenci; místo toho, když váš kód používá název elementu, kompilátor jazyka Visual Basic jej přeloží na stínovací prvek.

Účel

Hlavním účelem techniky "shadowing" je chránit definici členů vaší třídy. Základní třída může projít změnou, která vytvoří prvek se stejným názvem jako ten, který jste již definovali. Pokud k tomu dojde, modifikátor Shadows vynutí, aby se odkazy ve vaší třídě vyřešily na člena, kterého jste definovali, místo na nový element základní třídy.

Typy stínování

Prvek může stínovat jiný prvek dvěma různými způsoby. Stínující prvek lze deklarovat uvnitř podregionu oblasti obsahující stínovaný prvek, v takovém případě k stínování dochází prostřednictvím oboru. Případně může odvozená třída předefinovat člena základní třídy, v takovém případě se stínování provádí prostřednictvím dědičnosti.

Stínování prostřednictvím rozsahu

Programovací prvky ve stejném modulu, třídě nebo struktuře mohou mít stejný název, ale jiný obor. Pokud jsou tímto způsobem deklarovány dva prvky a kód odkazuje na název, který sdílejí, element s užším oborem stínuje druhý prvek (obor bloku je nejužší).

Modul může například definovat proměnnou Public s názvem tempa procedura v rámci modulu může deklarovat místní proměnnou také pojmenovanou temp. Odkazy na temp z procedury přistupují k místní proměnné, zatímco odkazy na temp mimo proceduru přistupují k proměnné Public. V tomto případě proměnná temp procedury stínuje proměnnou tempmodulu .

Následující obrázek znázorňuje dvě proměnné, obě pojmenované temp. Místní proměnná temp stínuje členovou proměnnou temp při přístupu v rámci vlastní procedury p. Klíčové slovo MyClass však obchází stínování a přistupuje k členské proměnné.

Obrázek znázorňující stínování pomocí zaměřovače

Příklad stínování v rámci oboru najdete v tématu Postupy: Skrytí proměnné se stejným názvem jako vaše proměnná.

Stínování prostřednictvím dědičnosti

Pokud odvozená třída předefinuje programovací prvek zděděný ze základní třídy, redefining element stínuje původní prvek. Můžete stínovat libovolný typ deklarovaného prvku nebo sadu přetížených prvků s jakýmkoli jiným typem. Proměnná Integer může například stínovat proceduru Function . Pokud stíníte proceduru s jinou procedurou, můžete použít jiný seznam parametrů a jiný návratový typ.

Následující obrázek znázorňuje základní třídu b a odvozenou třídu d , která dědí z b. Základní třída definuje proceduru s názvem proca odvozená třída ji stínuje s jiným postupem stejného názvu. První Call příkaz přistupuje ke stínování proc v odvozené třídě. MyBase Klíčové slovo však obchází stínování a přistupuje ke stínované procedurě v základní třídě.

Grafický diagram stínování prostřednictvím dědičnosti

Příklad stínování pomocí dědičnosti najdete v tématu Postupy: Skrytí proměnné se stejným názvem jako vaše proměnná a Postupy: Skrytí zděděné proměnné.

Úroveň stínování a přístupu

Stínovací prvek není vždy přístupný z kódu pomocí odvozené třídy. Může být například deklarována Private. V takovém případě je stínování zrušeno a kompilátor vyřeší jakýkoli odkaz na stejný prvek jako kdyby ke stínování nedošlo. Tento prvek je přístupným prvkem, který má nejméně odvozovacích kroků zpět od třídy stínování. Pokud stínovaný prvek je procedura, rozlišení je na nejbližší přístupnou verzi se stejným názvem, seznamem parametrů a návratovým typem.

Následující příklad ukazuje hierarchii dědičnosti tří tříd. Každá třída definuje proceduru Subdisplaya každá odvozená třída stínuje proceduru display v její základní třídě.

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  

Odvozená třída secondClass překrývá display pomocí procedury Private v předchozím příkladu. Při volání callDisplay v display modulem secondClass je volající kód mimo secondClass, a proto nemůže přistupovat k privátní proceduře display. Překrývání je vyřešeno a kompilátor vyřeší odkaz na proceduru základní třídy display.

Nicméně, další odvozená třída thirdClass deklaruje display jako Public, aby kód v callDisplay něm mohl získat přístup.

Stínování a přepsání

Nezaměňujte stínování s přetěžováním. Obě se používají, když odvozená třída dědí ze základní třídy a obě nahradí jeden deklarovaný prvek jiným. Mezi těmito dvěma ale existují významné rozdíly. Porovnání najdete v tématu Rozdíly mezi stínováním a přepsáním.

Stínování a přetížení

Pokud stínujete stejný prvek základní třídy s více než jedním prvkem v odvozené třídě, stínující prvky se stanou přetíženými verzemi tohoto prvku. Další informace naleznete v tématu Přetížení procedury.

Přístup ke stínovaným elementu

Když přistupujete k elementu z odvozené třídy, obvykle to provedete prostřednictvím aktuální instance této odvozené třídy tím, že opravníte název elementu s klíčovým slovem Me . Pokud odvozená třída stínuje prvek v základní třídě, můžete k elementu základní třídy získat přístup tím, že ho opravíte pomocí klíčového MyBase slova.

Příklad přístupu ke stínovaným elementu naleznete v tématu Postupy: Přístup k proměnné skryté odvozenou třídou.

Deklarace proměnné objektu

Způsob vytvoření proměnné objektu může ovlivnit také to, zda odvozená třída přistupuje k prvku, který zastíňuje, nebo ke stínovanému prvku. Následující příklad vytvoří dva objekty z odvozené třídy, ale jeden objekt je deklarován jako základní třída a druhý jako odvozená třída.

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  

V předchozím příkladu je proměnná basObj deklarována jako základní třída. Přiřazení objektu dervCls k němu představuje rozšiřující převod, a proto je platný. Základní třída však nemá přístup ke stínové verzi proměnné z v odvozené třídě, takže kompilátor přeloží basObj.z na původní hodnotu základní třídy.

Viz také