3

Why is overloading called compile time polymophism and overriding called runtime polymorphism? For example, have a look at the code below:

Public Class Animal
    Public Overridable Overloads Sub Eat()
        MsgBox("Animal Eat no arguement")
    End Sub
    Public Overridable Sub Drink()
        MsgBox("Animal drink arguement")
    End Sub
End Class

Public Class Horse
    Inherits Animal
    Public Overloads Overrides Sub Eat()
        MsgBox("Horse Eat no arguement")
    End Sub
    Public Overloads Sub Eat(ByVal food As String)
        MsgBox("Horse Eat food arguement")
    End Sub
    Public Overloads Overrides Sub Drink()
        MsgBox("Animal drink arguement")
    End Sub
End Class

Public Class Form1

    Private Sub Form2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim a1 As New Animal
        Dim a2 As Animal
        a2 = New Horse
        a1.Eat()
        a2.Eat("Fruit") 'line 6
    End Sub
End Class

Line 6 will cause a compile time error as the program stands. However, if I add an Eat(String) to the animal class then it will compile. What is the reasoning behind this?

Also the answer in the following post says: "The Overloads keyword is optional, but if you use it for one method, you must use it for all overloads of that method: "http://stackoverflow.com/questions/1173257/overloads-keyword-in-vb-net. I am not always finding this to be the case, if the function in question also Overrides. Is this the case?

I am looking through a large program that uses polymophism with interfaces. I have supplied the class above as an example for illustration purposes.

w0051977
  • 15,099
  • 32
  • 152
  • 329

2 Answers2

1

Line 6 will cause a compile time error as the program stands. However, if I add an Eat(String) to the animal class then it will compile. What is the reasoning behind this?

This is because the signature exposed by the type Animal does not have an Eat version with a string, until you modified the base class (Animal) signature. Polymorphism allows you to refer to a Horse as an Animal type, but only through the Animal's signature (unless you cast it to a horse type). So if you had another type Cat, which inherited from Animal, but didn't have eat(""), that would cause a compiler error if VB were to allow what you mentioned.

Also the answer in the following post says: "The Overloads keyword is optional, but if you use it for one method, you must use it for all overloads of that method

I think override provides that workaround you found, but not 100% sure about it. I personally don't use Overload at all to save on typing, and since C# doesn't use it.

Brian Mains
  • 50,520
  • 35
  • 148
  • 257
  • Thanks. I believe that as overriding is runtime polymorphism; that the signature of the Horse object is used. Why is the signature of the animal object used for overloading bu the signature of the horse object is used for overriding? – w0051977 Jul 23 '12 at 16:32
0

I don't know why they would call it compile time or runtime polymorphism, but I'll try to explain how it works:

Overriding a class member replaces the implementation of that member in the base class. This implies that you cannot override a member in its own class.

This doesn't compile:

Public Class Animal
    Public Overridable Sub Eat()
        ' eat whatever
    End Sub
    Public Overrides Sub Eat()
        ' eat whatever
    End Sub
End Class

This does compile:

Public Class Animal
    Public Overridable Sub Eat()
        ' eat whatever
    End Sub
End Class

Public Class Horse : Inherits Animal
    Public Overrides Sub Eat()
        ' eat whatever, except meat
    End Sub
End Class

In this example, I have replaced the original implementation with an implementation that does not allow the horse to eat meat. This disables any instance of Horse from eating meat products, even though the Animal type did not specify this limitation. However, to specify your own food type, you must add an overload that takes a string parameter.

Overloading a member allows you to choose either the original or the overload implementation. You can overload a member in the same class, or in a subclass that inherits from this base class. Or even in both classes.

This works:

Public Class Animal
    Public Overloads Sub Eat()
        ' eat whatever
    End Sub
    Public Overloads Sub Eat(food as String)
        ' eat food
    End Sub
End Class

This also works:

Public Class Animal
    Public Overloads Sub Eat()
        ' eat whatever
    End Sub
End Class

Public Class Horse : Inherits Animal
    Public Overloads Sub Eat(food as String)
        ' eat food
    End Sub
End Class

Conclusion

By overriding a member, you effectively disable the implementation of the base type. By overloading a member, you add an additional implementation, so either implementation can be used. You can override a member only once, but you can overload it as many times as needed.

Gotcha

If you create an instance of type Horse, but assign it to a variable of type Animal, only the members on the base class are visible, but they still use the implementation on the Horse type. To get around this, cast the instance of type Animal to the Horse type.

Steven Liekens
  • 13,266
  • 8
  • 59
  • 85