Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
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é.
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ě.
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.