다음을 통해 공유


Visual Basic의 섀도잉

두 프로그래밍 요소가 동일한 이름을 공유하는 경우 그중 하나가 다른 하나를 숨기거나 섀도잉할 수 있습니다. 이러한 상황에서는 섀도된 요소를 참조용으로 사용할 수 없습니다. 대신, 코드에서 요소 이름을 사용하는 경우 Visual Basic 컴파일러는 이를 섀도잉 요소로 확인합니다.

목적

섀도잉의 주요 목적은 클래스 멤버의 정의를 보호하는 것입니다. 기본 클래스는 이미 정의한 것과 이름이 같은 요소를 만드는 변경이 발생할 수 있습니다. 이 경우 Shadows 한정자는 클래스를 통해 참조를 강제로 새 기본 클래스 요소 대신 정의한 멤버로 확인합니다.

섀도잉 유형

요소는 두 가지 방법으로 다른 요소를 섀도할 수 있습니다. 섀도된 요소를 포함하는 영역의 하위 영역 내에서 섀도잉 요소를 선언할 수 있습니다. 이 경우 범위를 통해 섀도잉이 수행됩니다. 또는 파생 클래스는 기본 클래스의 멤버를 다시 정의할 수 있습니다. 이 경우 상속을 통해 섀도잉이 수행됩니다.

범위를 통한 섀도잉

동일한 모듈, 클래스 또는 구조체의 프로그래밍 요소는 이름은 같지만 범위는 다를 수 있습니다. 이러한 방식으로 두 요소가 선언되고 코드가 공유하는 이름을 참조하는 경우 범위가 더 좁은 요소는 다른 요소를 섀도합니다(블록 범위가 가장 좁음).

예를 들어 모듈은 이름이 tempPublic 변수를 정의할 수 있으며, 모듈 내의 프로시저는 이름이 temp인 지역 변수도 선언할 수 있습니다. 프로시저 내에서의 temp에 대한 참조는 지역 변수에 액세스하고, 프로시저 외부에서의 temp에 대한 참조는 Public 변수에 액세스합니다. 이 경우 프로시저 변수 temp은 모듈 변수 temp를 섀도합니다.

다음 그림에서는 이름이 temp인 두 변수를 보여 줍니다. 로컬 변수 temp은 자체 프로시저 p 내에서 액세스할 때 멤버 변수 temp를 섀도합니다. 그러나 MyClass 키워드는 섀도잉을 무시하고 멤버 변수에 액세스합니다.

Graphic that shows shadowing through scope.

범위를 통한 섀도잉의 예제는 방법: 이름이 같은 변수 숨기기를 참조하세요.

상속을 통한 섀도잉

파생 클래스가 기본 클래스에서 상속된 프로그래밍 요소를 다시 정의하면 재정의 요소가 원래 요소를 섀도합니다. 모든 형식의 선언된 요소 또는 오버로드된 요소 집합을 다른 형식으로 섀도하면 됩니다. 예를 들어 Integer 변수는 Function 프로시저를 섀도합니다. 다른 프로시저를 사용하여 프로시저를 섀도하면 다른 매개 변수 목록과 다른 반환 형식을 사용할 수 있습니다.

다음 그림에서는 기본 클래스 bb에서 상속되는 파생 클래스 d를 보여 줍니다. 기본 클래스는 이름이 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  

앞의 예제에서 파생 클래스 secondClassPrivate 프로시저를 사용하여 display를 섀도합니다. 모듈 callDisplaysecondClass에서 display를 호출하는 경우 호출 코드가 secondClass 외부에 있으므로 프라이빗 display 프로시저에 액세스할 수 없습니다. 섀도잉이 무효화되고 컴파일러는 기본 클래스 display 프로시저에 대한 참조를 확인합니다.

그러나 추가 파생 클래스 thirdClassdisplayPublic으로 선언하므로 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를 원래 기본 클래스 값으로 확인합니다.

참고 항목