Árnyékolás a Visual Basicben
Ha két programozási elem ugyanazzal a névvel rendelkezik, az egyik elrejtheti vagy árnyékba helyezheti a másikat. Ilyen esetben az árnyékolt elem nem használható referenciaként; ehelyett, ha a kód az elem nevét használja, a Visual Basic fordító feloldja azt az árnyékoló elemnek.
Cél
Az árnyékolás fő célja az osztálytagok definíciójának védelme. Előfordulhat, hogy az alaposztály olyan módosításon megy keresztül, amely egy olyan elemet hoz létre, amelynek neve megegyezik a már definiált névvel. Ha ez történik, a módosító arra Shadows
kényszeríti az osztályon keresztüli hivatkozásokat, hogy az új alaposztályelem helyett az Ön által meghatározott tagra legyenek feloldva.
Az árnyékolás típusai
Az elemek két különböző módon árnyékba helyezhetnek egy másik elemet. Az árnyékoló elem deklarálható az árnyékolt elemet tartalmazó régió egy alrégiójában, amely esetben az árnyékolás hatókörön keresztül történik. Vagy egy származtatott osztály újradefiniálta az alaposztály egy tagját, ebben az esetben az árnyékolás örökléssel történik.
Árnyékolás hatókörön keresztül
Az ugyanabban a modulban, osztályban vagy struktúrában lévő programozási elemek neve azonos, de hatóköre eltérő lehet. Ha két elem deklarálása így történik, és a kód a megosztott névre hivatkozik, a szűkebb hatókörrel rendelkező elem árnyékot képez a másik elemnek (a blokk hatóköre a legszűkebb).
Egy modul definiálhat például egy elnevezett temp
változótPublic
, a modulon belüli eljárás pedig deklarálhat egy helyi változót is.temp
temp
Az eljáráson belüli hivatkozások a helyi változóhoz temp
férnek hozzá, míg az eljáráson kívüli hivatkozások hozzáférnek a Public
változóhoz. Ebben az esetben az eljárásváltozó temp
árnyékot ad a modulváltozónak temp
.
Az alábbi ábrán két változó látható, mindkettő neve temp
. A helyi változó temp
árnyékot ad a tagváltozónak temp
, amikor az a saját eljárásán p
belül érhető el. A MyClass
kulcsszó azonban áthalad az árnyékoláson, és hozzáfér a tagváltozóhoz.
A hatókörön keresztüli árnyékolásra példa: Útmutató: Változó elrejtése ugyanazzal a névvel, mint a változó.
Árnyékolás örökléssel
Ha egy származtatott osztály újradefiniálja az alaposztálytól örökölt programozási elemet, az újradefiniáló elem árnyékba helyezi az eredeti elemet. Bármilyen deklarált elem vagy túlterhelt elemcsoport árnyékolása bármilyen más típussal. Egy változó például Integer
árnyékot adhat egy eljárásnak Function
. Ha egy eljárást egy másik eljárással árnyékolással árnyékel, használhat egy másik paraméterlistát és egy másik visszatérési típust.
Az alábbi ábra egy alaposztályt b
és egy származtatott osztályt d
mutat be, amely a következőtől b
öröklődik: Az alaposztály egy elnevezett proc
eljárást határoz meg, és a származtatott osztály egy másik, azonos nevű eljárással árnyékozza azt. Az első Call
utasítás hozzáfér az árnyékoláshoz proc
a származtatott osztályban. A MyBase
kulcsszó azonban áthalad az árnyékoláson, és hozzáfér az árnyékolt eljáráshoz az alaposztályban.
Az öröklésen keresztüli árnyékolásra példa: Útmutató: Változó elrejtése ugyanazzal a névvel, mint a változó , és útmutató: Örökölt változó elrejtése.
Árnyékolás és hozzáférési szint
Az árnyékoló elem nem mindig érhető el a kódból a származtatott osztály használatával. Deklarálható Private
például . Ilyen esetben az árnyékolás le lesz állítva, és a fordító felold minden olyan hivatkozást, amely ugyanahhoz az elemhez lett volna, ha nem lett volna árnyékolás. Ez az elem az az akadálymentes elem, amely a legkevesebb származtatott lépés az árnyékolási osztálytól visszafelé. Ha az árnyékolt elem egy eljárás, a megoldás a legközelebbi elérhető verzióhoz tartozik, ugyanazzal a névvel, paraméterlistával és visszatérési típussal.
Az alábbi példa három osztály öröklési hierarchiáját mutatja be. Minden osztály meghatároz egy Sub
eljárást display
, és minden származtatott osztály árnyékot ad az eljárásnak az display
alaposztályában.
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
Az előző példában a származtatott osztály secondClass
árnyékai display
egy Private
eljárással. Amikor a modul callDisplay
meghívja a modult display
secondClass
, a hívókód kívül secondClass
esik, ezért nem fér hozzá a privát display
eljáráshoz. Az árnyékolás sikertelen, és a fordító feloldja az alaposztály-eljárásra display
való hivatkozást.
A további származtatott osztály thirdClass
azonban úgy deklarál display
, hogy Public
a benne lévő callDisplay
kód hozzáférhessen.
Árnyékolás és felülírás
Ne keverje össze az árnyékolást a felülírással. Mindkettő akkor használatos, ha egy származtatott osztály örökli az alaposztályt, és mindkettő újradefiniálja az egyik deklarált elemet egy másikkal. A kettő között azonban jelentős különbségek vannak. Összehasonlításért tekintse meg az árnyékolás és a felülírás közötti különbségeket.
Árnyékolás és túlterhelés
Ha ugyanazt az alaposztály-elemet árnyékozza, amelynek több eleme is van a származtatott osztályban, az árnyékoló elemek az elem túlterhelt verzióivá válnak. További információ: Eljárás túlterhelése.
Árnyékolt elem elérése
Ha egy elemet egy származtatott osztályból ér el, ezt általában az adott származtatott osztály aktuális példányán keresztül teheti meg úgy, hogy az elem nevét a Me
kulcsszóval minősíti. Ha a származtatott osztály árnyékot ad az alaposztály elemének, a kulcsszóval való minősítéssel elérheti az MyBase
alaposztály-elemet.
Egy árnyékolt elem elérésére példa: Hogyan lehet elérni egy változót rejtett egy származtatott osztály által.
Az objektumváltozó deklarációja
Az objektumváltozó létrehozása azt is befolyásolhatja, hogy a származtatott osztály hozzáfér-e egy árnyékoló elemhez vagy az árnyékolt elemhez. Az alábbi példa két objektumot hoz létre egy származtatott osztályból, de az egyik objektum alaposztályként, a másik pedig származtatott osztályként van deklarálva.
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
Az előző példában a változó basObj
alaposztályként van deklarálva. Egy dervCls
objektum hozzárendelése szélesítő átalakítást jelent, ezért érvényes. Az alaposztály azonban nem fér hozzá a változó z
árnyékolt verziójához a származtatott osztályban, ezért a fordító az eredeti alaposztály-értékre oldja fel a problémát basObj.z
.