none
Shadowing through inheritance RRS feed

  • Question

  • Hi,

    Please help me understand the role of the SHADOWS keyword in shadowing through inheritance.

    My question is : When the DoSomething method in the derived class is called through c.UseMe(), the SHADOWS keyword is behaving differently compared to when the  DoSomething method in the derived class is called directly through c.DoSomething()Why is this difference in behaviour of the SHADOWS keyword?

    I wrote the following code and have explained my understanding below. Please tell me where I am going wrong:

    1. STEP 1: Calls the useMe method in class PERSON
    2. STEP 2: Me keyowrd behaves like an object referring to a current instance
    3. STEP 3: Hence Me.DoSomething = c.DoSOmething and hence control should move to derived class
    4. STEP 4: Once the control moves to the derived class, the compiler should execute the DoSomething in the derived class as it has shadowed the DoSomething in the base class. Hence the Output should be "Customer". But the output is "Person"

    Module Module1
    
        Sub main()
            Dim c As New Customer()
            c.UseMe() 'STEP 1 
            Console.WriteLine("----")
            c.DoSomething()
            Console.ReadLine()
        End Sub
    
    End Module
    
    Public Class Person
        Public Sub DoSomething()
            Console.WriteLine("Person")
        End Sub
    
        Public Sub UseMe()
            Me.DoSomething() 'STEP 2
            'STEP 3
        End Sub
    End Class
    Public Class Customer
        Inherits Person
        Public Shadows Sub DoSomething()
            'STEP 4
            Console.WriteLine("Customer")
        End Sub
    End Class

    The output I am getting is as follows:

    The control flow, as per my understanding is as follows (its not happening like this although):

    So requesting help to understand why SHADOWS behave on expected lines when we use c.DoSomething() but behaves differently (i.e. does not execute the derived class method) when called through ME in the statement c.UseMe().



    Sougata Ghosh

    Monday, December 9, 2019 6:52 AM

Answers

  • Hi,

    When you use public shadows in a derived class, it will hide the methods in the base class,, similar to Overrides (but it does not mean that they are the same) ,so c.DoSomething () will call the methods in the derived class and output "Customer".

    But when you call c.UseMe (), there is no such method that be overrided in the derived class, so you have to find it in the base class. After finding the UseMe () method in the base class,then the programe call back the DoSomething() method in the base class, and finally output "Person".

    If you want to output "Customer", you can override Public shadows Sub UseMe () in the derived class Customer.

    In addition, when you use private shadows in a derived class, the object does not have permission to access the methods in the derived class, so it can only access the methods in the base class, which will output "person".

    Please check in the following codes:

    Module Module1
    
        Sub main()
            Dim c As New Customer()
            c.UseMe()
            Console.WriteLine("----")
            c.DoSomething()
            Console.ReadLine()
        End Sub
    
    
        Public Class Person
        Public Sub DoSomething()
            Console.WriteLine("Person")
        End Sub
    
        Public Sub UseMe()
                Me.DoSomething()
            End Sub
    End Class
    Public Class Customer
        Inherits Person
            Public Shadows Sub DoSomething()
                Console.WriteLine("Customer")
            End Sub
    
            Public Shadows Sub UseMe()
                Me.DoSomething()
            End Sub
        End Class
    
    End Module

    As for other possible question, you can try my following code for more details.

    Module Module1
    
        Class A
            Public Overridable Sub Show()
                Console.WriteLine("Calling from A")
            End Sub
    
            Public Sub Useme()
                Me.Show()
            End Sub
        End Class
    
        Class B
            Inherits A
            Public Shadows Sub Show()
                Console.WriteLine("Calling from B")
            End Sub
    
            Public Shadows Sub Useme()
                Me.Show()
            End Sub
        End Class
    
        Class C
            Inherits A
            Private Shadows Sub Show()
                Console.WriteLine("Calling from C")
            End Sub
    
            Private Shadows Sub Useme()
                Me.Show()
            End Sub
        End Class
    
        Class D
            Inherits A
            Public Shadows Sub Show()
                Console.WriteLine("Calling from D")
            End Sub
    
            Private Shadows Sub Useme()
                Me.Show()
            End Sub
        End Class
    
        Class E
            Inherits A
            Private Shadows Sub Show()
                Console.WriteLine("Calling from E")
            End Sub
    
            Public Shadows Sub Useme()
                Me.Show()
            End Sub
        End Class
    
        Class F
            Inherits A
            Public Shadows Sub Show()
                Console.WriteLine("Calling from F")
            End Sub
    
        End Class
    
        Class G
            Inherits A
            Private Shadows Sub Show()
                Console.WriteLine("Calling from G")
            End Sub
    
        End Class
    
        Sub Main()
    
            Dim a As A
            a = New A()
            a.Show()
            a.Useme()
            a = New B()
            a.Show()
            a.Useme()
            a = New C()
            a.Show()
            a.Useme()
            a = New D()
            a.Show()
            a.Useme()
            a = New E()
            a.Show()
            a.Useme()
            Console.WriteLine("----------")
    
    
            Dim b As B
            b = New B()
            b.Show()
            b.Useme()
            Console.WriteLine("----------")
    
            Dim c As C
            c = New C()
            c.Show()
            c.Useme()
            Console.WriteLine("----------")
    
            Dim d As D
            d = New D()
            d.Show()
            d.Useme()
            Console.WriteLine("----------")
    
            Dim e As E
            e = New E()
            e.Show()
            e.Useme()
            Console.WriteLine("----------")
    
            Dim f As F
            f = New F()
            f.Show()
            f.Useme()
            Console.WriteLine("----------")
    
            Dim g As G
            g = New G()
            g.Show()
            g.Useme()
            Console.WriteLine("----------")
    
            Console.ReadKey()
    
        End Sub
    
    End Module

    Hope it be helpful.

    Best Regards,

    Julie


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Tuesday, December 10, 2019 6:32 AM
    Moderator

All replies

  • Hi

    Perhaps THIS link will help.

    Extract:

    • Accessing. The shadowed element in the base class is normally unavailable from within the derived class that shadows it. However, the following considerations apply.

      • If the shadowing element is not accessible from the code referring to it, the reference is resolved to the shadowed element. For example, if a Private element shadows a base class element, code that does not have permission to access the Private element accesses the base class element instead.

      • If you shadow an element, you can still access the shadowed element through an object declared with the type of the base class. You can also access it through MyBase.


    Regards Les, Livingston, Scotland

    Monday, December 9, 2019 1:18 PM
  • Hi

    Perhaps THIS link will help.

    Extract:

    • Accessing. The shadowed element in the base class is normally unavailable from within the derived class that shadows it. However, the following considerations apply.

      • If the shadowing element is not accessible from the code referring to it, the reference is resolved to the shadowed element. For example, if a Private element shadows a base class element, code that does not have permission to access the Private element accesses the base class element instead.

      • If you shadow an element, you can still access the shadowed element through an object declared with the type of the base class. You can also access it through MyBase.


    Regards Les, Livingston, Scotland

    Hi,

    Thanks for the article but I had already read it...infact it is the source of my confusion. The first point is not relevant here. In the second point there are two conditions mentioned under which the shadowed element can be accessed and I am doing neither. They are:

    1.  BY declaring an object of type base class - Object "c" is of the derived type (Customer)
    2.  By using MyBase - We are using ME here. Not MyBase. Infact it is clearly written in the following article that: Check this link

    Accessing a Shadowed Element

    When you access an element from a derived class, you normally do so through the current instance of that derived class, by qualifying the element name with the Me keyword.

    Isnt this exactly what I am doing? In my code, c.UseMe() calls the UseMe() in the base class. Then the Me.DoSomething should send the control to the derived class as ME works as a object referring to current instance "c" which is of the derived class type and execute the DoSomething in the derived class. but somehow that is not happening.....why?


    Sougata Ghosh



    • Edited by sougata12 Monday, December 9, 2019 5:33 PM
    Monday, December 9, 2019 5:24 PM
  • Hi,

    When you use public shadows in a derived class, it will hide the methods in the base class,, similar to Overrides (but it does not mean that they are the same) ,so c.DoSomething () will call the methods in the derived class and output "Customer".

    But when you call c.UseMe (), there is no such method that be overrided in the derived class, so you have to find it in the base class. After finding the UseMe () method in the base class,then the programe call back the DoSomething() method in the base class, and finally output "Person".

    If you want to output "Customer", you can override Public shadows Sub UseMe () in the derived class Customer.

    In addition, when you use private shadows in a derived class, the object does not have permission to access the methods in the derived class, so it can only access the methods in the base class, which will output "person".

    Please check in the following codes:

    Module Module1
    
        Sub main()
            Dim c As New Customer()
            c.UseMe()
            Console.WriteLine("----")
            c.DoSomething()
            Console.ReadLine()
        End Sub
    
    
        Public Class Person
        Public Sub DoSomething()
            Console.WriteLine("Person")
        End Sub
    
        Public Sub UseMe()
                Me.DoSomething()
            End Sub
    End Class
    Public Class Customer
        Inherits Person
            Public Shadows Sub DoSomething()
                Console.WriteLine("Customer")
            End Sub
    
            Public Shadows Sub UseMe()
                Me.DoSomething()
            End Sub
        End Class
    
    End Module

    As for other possible question, you can try my following code for more details.

    Module Module1
    
        Class A
            Public Overridable Sub Show()
                Console.WriteLine("Calling from A")
            End Sub
    
            Public Sub Useme()
                Me.Show()
            End Sub
        End Class
    
        Class B
            Inherits A
            Public Shadows Sub Show()
                Console.WriteLine("Calling from B")
            End Sub
    
            Public Shadows Sub Useme()
                Me.Show()
            End Sub
        End Class
    
        Class C
            Inherits A
            Private Shadows Sub Show()
                Console.WriteLine("Calling from C")
            End Sub
    
            Private Shadows Sub Useme()
                Me.Show()
            End Sub
        End Class
    
        Class D
            Inherits A
            Public Shadows Sub Show()
                Console.WriteLine("Calling from D")
            End Sub
    
            Private Shadows Sub Useme()
                Me.Show()
            End Sub
        End Class
    
        Class E
            Inherits A
            Private Shadows Sub Show()
                Console.WriteLine("Calling from E")
            End Sub
    
            Public Shadows Sub Useme()
                Me.Show()
            End Sub
        End Class
    
        Class F
            Inherits A
            Public Shadows Sub Show()
                Console.WriteLine("Calling from F")
            End Sub
    
        End Class
    
        Class G
            Inherits A
            Private Shadows Sub Show()
                Console.WriteLine("Calling from G")
            End Sub
    
        End Class
    
        Sub Main()
    
            Dim a As A
            a = New A()
            a.Show()
            a.Useme()
            a = New B()
            a.Show()
            a.Useme()
            a = New C()
            a.Show()
            a.Useme()
            a = New D()
            a.Show()
            a.Useme()
            a = New E()
            a.Show()
            a.Useme()
            Console.WriteLine("----------")
    
    
            Dim b As B
            b = New B()
            b.Show()
            b.Useme()
            Console.WriteLine("----------")
    
            Dim c As C
            c = New C()
            c.Show()
            c.Useme()
            Console.WriteLine("----------")
    
            Dim d As D
            d = New D()
            d.Show()
            d.Useme()
            Console.WriteLine("----------")
    
            Dim e As E
            e = New E()
            e.Show()
            e.Useme()
            Console.WriteLine("----------")
    
            Dim f As F
            f = New F()
            f.Show()
            f.Useme()
            Console.WriteLine("----------")
    
            Dim g As G
            g = New G()
            g.Show()
            g.Useme()
            Console.WriteLine("----------")
    
            Console.ReadKey()
    
        End Sub
    
    End Module

    Hope it be helpful.

    Best Regards,

    Julie


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Tuesday, December 10, 2019 6:32 AM
    Moderator
  • Hello,

    On the basis of the original, I modified my reply a bit, it should be clearer than the original to help you understand the shadows keyword.

    Hope it be helpful.

    Best Regards,

    Julie


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Tuesday, December 10, 2019 7:03 AM
    Moderator
  • Hello,

    On the basis of the original, I modified my reply a bit, it should be clearer than the original to help you understand the shadows keyword.

    Hope it be helpful.

    Best Regards,

    Julie


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    sorry for this late reply but many thanks for this extra effort

    Sougata Ghosh

    Saturday, December 14, 2019 6:24 AM