Finally, the final of the 4 posts on object-oriented principles for
those of you just coming to .Net from non-OOP languages. Data Abstraction, Encapsulation and Inheritance we have already discussed. Now we will talk about polymorphism.
Polymorphism means one name, many forms. Polymorphism
manifests itself by having multiple methods all with the same name, but
slighty different functionality. Updated statement: Polymorphism can be
coupled with inheritance, but inheritance is not a requirement to gain
polymorphic behaviors. Because of this, it can be difficult to
fully grasp the full potential of polymorphism until you get some
practice with it and see exactly what happens under different
scenarios. We’re only going to talk about polymorphism, like
the other topics, at the basic level.
There are 2 basic types of polymorphism. Overridding, also
called run-time polymorphism, and overloading, which is referred to as
compile-time polymorphism. This difference is, for method
overloading, the compiler determines which method will be
executed, and this decision is made when the code gets compiled.
Which method will be used for method overriding is determined at
runtime based on the dynamic type of an object.
Let’s look at some code:
You see our library asset class. Pay attention to the
overridable function CalculateFineTotal(). In LibraryAsset, we
have defined the default functionality for this method that any derived
classes can use. Any class derived from LibraryAsset can use this
default behavior and calculate fines based on the default
implementation of $1.25 per day late. This is true for our
Magazine class. We didn’t override the function so when late fees
are calculated for late magazine returns, it will use the default
Now look at the book class. We have overridden the
CalculateFineTotal to use a different value when determining late
fees. The overrides keywork in VB tells the caller that any
method call will use the virtual method found in Book, not the default
implementation found in LibraryAsset. We have implemented runtime
polymorphism – method overriding.
Lets move on to AudioCassette. Here we have the same method
overriding we found in the book class. Fines are calculated based
on $0.25 per day. Notice we’ve added something extra. We’ve
added the Overloads keywork to our function and to a new function with
the same name, except the new function now accepts a parameter.
Now the caller can call either method, and depending on whether or not
a parameter is passed, that determines with method will be
executed. Notice we do not include the overrides keywork in the
2nd function with a parameter. This is because not method exists
in LibraryAsset with that same signature (accepting a parameter of type
double). You can only override methods with the same signature in
a base class.
Now lets look at some code that creates all these library items and
checks them in and cacluates our fines based on returning them 3 days
The output will look like the following:
You can see how all of our output was different, based on the method
that was executed. We created a new Magazine, which is a type of
LibraryAsset. That is why the instantiation says “myMagazine As
LibraryAsset”. However, since we actually want a magazine, we
create a “New Magazine”. Same thing with book. For Book,
its a little bit more tricky. Since we created a Book of the type
LibraryAsset, this is where the polymorphism comes into play.
Book overrides the CalculateFineTotal of LibraryAsset.
Audiocassette is a little bit different. It actually extends the
implementation of LibraryAsset by including an overloaded function for
CalculateFineTotal(). If we weren’t going to use the function
that took a parameter, we would create it the same way we created the
Book and Magazine classes. But in order to use the overloaded
function, we have to create a new AudioCassette of the type
AudioCassette, because LibraryAsset doesn’t support the overloaded
Only the Magazine used the default method found in the base
class. Book and AudioCassette used their own implementations of
the method. Also, at compile time, the decision was made which
method would be used when we calculate amountDue for the AudioCassette
class. The first call used the 1st method in AudioCassette
without parameters. The 2nd call used the 2nd method with a