Поделиться через


Сокрытие в Visual Basic

Если два элемента программирования имеют одно и то же имя, один из них может скрыть или тень, другой. В такой ситуации теневой элемент недоступен для ссылки; Вместо этого, когда код использует имя элемента, компилятор Visual Basic разрешает его в элемент теневого тенирования.

Характер использования

Основной целью тени является защита определения членов класса. Базовый класс может пройти изменение, создающее элемент с тем же именем, что и уже определенный. В этом случае Shadows модификатор принудительно ссылается на класс, который необходимо разрешить определенному элементу, а не к новому элементу базового класса.

Типы тени

Элемент может тень другого элемента двумя разными способами. Элемент тени можно объявить внутри региона, содержащего теневой элемент, в котором выполняется тень, через область. Или производный класс может переопределить член базового класса, в этом случае тень выполняется через наследование.

Тени через область

Для элементов программирования в одном модуле, классе или структуре может быть одинаковое имя, но разные область. Когда два элемента объявляются таким образом и код ссылается на имя, к которым они используются, элемент с более узким область тени другого элемента (блок область является самым узким).

Например, модуль может определить Public переменную с именем temp, и процедура в модуле может объявлять локальную переменную также с именем temp. Ссылки на temp из процедуры обращаются к локальной переменной, а ссылки на внешние ссылки на процедуру обращаются temp к переменной Public . В этом случае переменная temp процедуры тени переменной tempмодуля.

На следующем рисунке показаны две переменные с именами temp. Локальная переменная temp тенирует переменную-член temp при доступе из собственной процедуры p. MyClass Однако ключевое слово проходит тень и обращается к переменной-члену.

Graphic that shows shadowing through scope.

Пример тени с помощью область см. в статье "Практическое руководство. Скрытие переменной с тем же именем, что и переменная".

Тени через наследование

Если производный класс переопределяет элемент программирования, унаследованный от базового класса, элемент переопределения тени исходного элемента. Вы можете тени любого типа объявленного элемента или набора перегруженных элементов с любым другим типом. Например, переменная Integer может затенить процедуру Function . При тени процедуры с другой процедурой можно использовать другой список параметров и другой тип возвращаемого значения.

На следующем рисунке показан базовый класс b и производный класс d , наследующий от b. Базовый класс определяет процедуру с именем proc, а производный класс тенирует его с другой процедурой того же имени. Call Первая инструкция обращается к тени proc в производном классе. MyBase Однако ключевое слово проходит тень и обращается к теневой процедуре в базовом классе.

Graphic diagram of shadowing through inheritance

Пример теневого наследования см. в статье "Практическое руководство. Скрытие переменной с тем же именем, что и переменная и практическое руководство. Скрытие унаследованной переменной".

Уровень тени и доступа

Элемент тени не всегда доступен из кода с помощью производного класса. Например, его можно объявить Private. В таком случае тень побеждена, и компилятор разрешает любую ссылку на тот же элемент, который он имел бы, если бы не было тени. Этот элемент является доступным элементом, который является наименьшим производным шагом назад от теневой класса. Если теневой элемент является процедурой, разрешение — к ближайшей доступной версии с тем же именем, списком параметров и типом возвращаемого значения.

В следующем примере показана иерархия наследования трех классов. Каждый класс определяет процедуру, а каждый производный Sub класс тени display процедуры 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  

В предыдущем примере производный класс secondClass теняется display с процедурой Private . При вызове display secondClassмодуля callDisplay код вызова находится вне secondClass и поэтому не может получить доступ к частной display процедуре. Тень побеждена, и компилятор разрешает ссылку на процедуру базового класса display .

Однако дальнейший производный класс thirdClass объявляется display как Public, поэтому код в callDisplay нем может получить доступ.

Тень и переопределение

Не путайте тени с переопределением. Оба используются, когда производный класс наследует от базового класса, и оба переопределяют один объявленный элемент с другим. Но между этими двумя существуют значительные различия. Сравнение см. в разделе "Различия между теневым и переопределением".

Тень и перегрузка

Если вы тенируете один и тот же элемент базового класса с несколькими элементами в производном классе, теневые элементы становятся перегруженными версиями этого элемента. Дополнительные сведения см. в разделе Procedure Overloading.

Доступ к теневому элементу

При доступе к элементу из производного класса обычно это выполняется с помощью текущего экземпляра этого производного класса, присвоив имя элемента ключевое слово Me . Если производный класс теняет элемент в базовом классе, вы можете получить доступ к элементу базового класса, квалифицируя его с MyBase помощью ключевое слово.

Пример доступа к теневой элементу см. в статье "Практическое руководство. Доступ к переменной, скрытой производным классом".

Объявление переменной объекта

Создание переменной объекта также может повлиять на то, обращается ли производный класс к теневой элементу или теневой элемент. В следующем примере создаются два объекта из производного класса, но один объект объявлен как базовый класс, а другой — производным классом.

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  

В предыдущем примере переменная basObj объявляется как базовый класс. Назначение dervCls объекта ему представляет собой расширение преобразования, поэтому является допустимым. Однако базовый класс не может получить доступ к теневой версии переменной z в производном классе, поэтому компилятор разрешает basObj.z исходное значение базового класса.

См. также