abstract classes and polymorphism

sainathdk

New member
Joined
Jan 25, 2008
Messages
2
Programming Experience
3-5
I am having difficulty in understanding how the below code is working.

The goal is to have two abstract classes A and B. Then a variable declared of type A, will call the corresponding implementation of GetCost method, of any concrete class that inherits B (in this example C).

In Main, I have created an instance of C and assigned it to variable x, of type A. Every time I run this code, the value I get is 1, instead of 3.

If possible, I would like to keep both the methods abstract in class A and class B and just implement in C. I want to use abstract classes and not an interface.

Any help/guidance will be appreciated.

Module Module1
Sub Main()
Dim x As A = New C
Console.WriteLine(x.Getcost())
Console.ReadLine()
End Sub

Public MustInherit Class A
Public Overridable Function Getcost() As Decimal
Return 1
End Function
End Class

Public MustInherit Class B
Inherits A
Public MustOverride Shadows Function Getcost() As Decimal
End Class

Public Class C
Inherits B

Public Overrides Function GetCost() As Decimal
Return 3
End Function
End Class
End Module
 
The problem is the fact that you're using the Shadows key word in class B. It's important to understand the difference between overriding and shadowing a method. When you override a method you are simply providing a new implementation for the same method. When you shadow a method you are actually creating a completely new method that happens to have the same name as the one in the base class.

Overriding follows the object type while shadowing follows the variable type. So, let's say you have these two classes:
VB.NET:
Public Class BaseClass

    Public Overridable Sub MethodA()
        MessageBox.Show("BaseClass.MethodA")
    End Sub

    Public Sub MethodB()
        MessageBox.Show("BaseClass.MethodB")
    End Sub

End Class


Public Class DerivedClass
    Inherits BaseClass

    Public Overrides Sub MethodA()
        MessageBox.Show("DerivedClass.MethodA")
    End Sub

    Public Shadows Sub MethodB()
        MessageBox.Show("DerivedClass.MethodB")
    End Sub

End Class
Now run this code and see what happens:
VB.NET:
Dim dc As New DerivedClass

dc.MethodA()
dc.MethodB()

Dim bc As BaseClass = dc

bc.MethodA()
bc.MethodB()
The first two messages show that you're invoking MethodA and MethodB of the DerivedClass, as you'd expect.

The next message shows that you are invoking MethodA of the DerivedClass. That's because MethodA is overridden in DerivedClass and overriding follows the type of the object. The object is type DerivedClass so it's DerivedClass.MethodA that gets invoked.

The last message shows that you're invoking MethodB of the BaseClass. That's because MethodB is shadowed in DerivedClass and shadowing follows the type of the variable. The variable is type BaseClass so it's BaseClass.MethodB that gets invoked.

Now, you have shadowed the Getcost method in class B, so it's that new method that you're overriding in class C, not the original method from class A. If you use a variable of type A then you will be invoking methods of class A. A.Getcost is never overridden so you are invoking the original implementation. If you want follow the type of the object then you must override and not shadow.
 
jmcilhinney, thank you for the detailed explanation. It helped get my concept straight

I removed the shadows and added the overrides keyword to the Getcost in Class B and voila!, It worked
 
Back
Top