Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Quando dois elementos de programação compartilham o mesmo nome, um deles pode ocultar, ou sombra, o outro. Nessa situação, o elemento sombreado não está disponível para referência; Em vez disso, quando o código usa o nome do elemento, o compilador do Visual Basic o resolve para o elemento de sombreamento.
Propósito
A principal finalidade do sombreamento é proteger a definição dos seus membros de classe. A classe base pode passar por uma alteração que cria um elemento com o mesmo nome que você já definiu. Se isso acontecer, o modificador Shadows
força as referências por meio de sua classe a serem resolvidas para o membro que você definiu, em vez de para o novo elemento de classe base.
Tipos de Sombreamento
Um elemento pode sombrear outro elemento de duas maneiras diferentes. O elemento de sombreamento pode ser declarado dentro de uma subregião da região que contém o elemento sombreado, nesse caso, o sombreamento é realizado por meio do escopo. Ou uma classe derivada pode redefinir um membro de uma classe base, nesse caso, o sombreamento é feito por meio de herança.
Sombreamento por Escopo
É possível que os elementos de programação no mesmo módulo, classe ou estrutura tenham o mesmo nome, mas escopo diferente. Quando dois elementos são declarados dessa maneira e o código se refere ao nome que compartilham, o elemento com o escopo mais estreito sombreia o outro elemento (o escopo do bloco é o mais estreito).
Por exemplo, um módulo pode definir uma Public
variável nomeada temp
e um procedimento dentro do módulo pode declarar uma variável local também chamada temp
. As referências de temp
dentro do procedimento acessam a variável local, enquanto as referências de temp
fora do procedimento acessam a Public
variável. Nesse caso, a variável temp
de procedimento sombreia a variável temp
do módulo.
A ilustração a seguir mostra duas variáveis, ambas nomeadas temp
. A variável temp
local sombreia a variável temp
de membro quando acessada de dentro de seu próprio procedimento p
. No entanto, a MyClass
palavra-chave ignora o sombreamento e acessa a variável de membro.
Para obter um exemplo de sombreamento por meio do escopo, consulte Como Ocultar uma Variável com o Mesmo Nome que sua Variável.
Sombreamento por Herança
Se uma classe derivada redefine um elemento de programação herdado de uma classe base, o elemento de redefinição sombreia o elemento original. Você pode sombrear qualquer tipo de elemento declarado ou conjunto de elementos sobrecarregados com qualquer outro tipo. Por exemplo, uma Integer
variável pode sombrear um Function
procedimento. Se você sombrear um procedimento com outro procedimento, poderá usar uma lista de parâmetros diferente e um tipo de retorno diferente.
A ilustração a seguir mostra uma classe b
base e uma classe d
derivada que herda de b
. A classe base define um procedimento chamado proc
e a classe derivada o sombreia com outro procedimento de mesmo nome. A primeira instrução Call
acessa o sombreamento proc
na classe derivada. No entanto, a MyBase
palavra-chave ignora o sombreamento e acessa o procedimento sombreado na classe base.
Para obter um exemplo de sombreamento por meio da herança, consulte Como ocultar uma variável com o mesmo nome da variável e como ocultar uma variável herdada.
Sombreamento e nível de acesso
O elemento de sombreamento nem sempre é acessível do código usando a classe derivada. Por exemplo, ele pode ser declarado Private
. Nesse caso, o sombreamento é derrotado e o compilador resolve qualquer referência ao mesmo elemento que teria se não houvesse sombreamento. Esse elemento é o elemento acessível que menos passos derivacionais para trás da classe de sombreamento. Se o elemento sombreado for um procedimento, a resolução será para a versão acessível mais próxima com o mesmo nome, lista de parâmetros e tipo de retorno.
O exemplo a seguir mostra uma hierarquia de herança de três classes. Cada classe define um Sub
procedimento display
e cada classe derivada sombreia o display
procedimento em sua classe base.
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
No exemplo anterior, a classe derivada secondClass
sombreia display
com um procedimento Private
. Quando o módulo callDisplay
chama display
em secondClass
, o código de chamada está fora de secondClass
e, portanto, não pode acessar o procedimento privado display
. O sombreamento é resolvido, e o compilador resolve a referência ao procedimento da classe base display
.
No entanto, a classe ainda mais derivada thirdClass
declara display
como Public
, de modo que o código em callDisplay
pode acessá-la.
Sombreamento e Substituição
Não confunda sombreamento com substituição. Ambos são usados quando uma classe derivada herda de uma classe base e redefinem um elemento declarado com outro. Mas há diferenças significativas entre os dois. Para uma comparação, consulte Diferenças entre Sombreamento e Substituição.
Sombreamento e sobrecarga
Se você sombrear o mesmo elemento de classe base com mais de um elemento em sua classe derivada, os elementos de sombreamento se tornarão versões sobrecarregadas desse elemento. Para obter mais informações, consulte Sobrecarga de Procedimento.
Acessando um elemento sombreado
Quando você acessa um elemento de uma classe derivada, normalmente faz isso por meio da instância atual dessa classe derivada, qualificando o nome do elemento com a Me
palavra-chave. Se a classe derivada sombrear o elemento na classe base, você poderá acessar o elemento de classe base qualificando-o com a MyBase
palavra-chave.
Para obter um exemplo de acesso a um elemento sombreado, consulte Como acessar uma variável oculta por uma classe derivada.
Declaração da variável de objeto
Como você cria a variável de objeto também pode afetar se a classe derivada acessa um elemento de sombreamento ou o elemento sombreado. O exemplo a seguir cria dois objetos de uma classe derivada, mas um objeto é declarado como a classe base e o outro como a classe derivada.
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
No exemplo anterior, a variável basObj
é declarada como a classe base. Atribuir um dervCls
objeto a ele constitui uma conversão de ampliação e, portanto, é válido. No entanto, a classe base não pode acessar a versão de sombreamento da variável z
na classe derivada, portanto, o compilador resolve basObj.z
para o valor de classe base original.