Polymorphism
In previous articles, you have seen how a class encapsulates data and how a
class can inherit the capabilities of a base class while adding its own. The
third great principle of Object Oriented Programming is Polymorphism which
enables a class to change existing behaviours to suit new requirements.
The term polymorphism covers a number of important areas of software
architecture. In the example on inheritance you have effectively already seen
one type of polymorphism because the derived class both inherited from the base
class and also added its own capabilities. This is probably the most common
usage and is called Subtype Polymorphism. because the
sub class extends the capabilities of the base thereby enabling the system to
evolve.
In object orientation there are many different sorts of polymorphic behaviour. A
classic example is that of the virtual method which is overidden to provide a
specific behaviour in the derived class.
Overload polymorphism
Imagine a Car object as being a general thing. Cars may fall into many sub types
but they all have the common behaviour of being able to drive.
A base class representing a Car object would have a method called Drive that
would enable it to perform this task. The specific type of car however might
handle the task of driving in different ways.
The general case Car object can define the Drive method as a "virtual method"
which may be overidden by derived classes to perform the Drive function in
different ways. Here is the Car base class:
class Car
{
public virtual
string Drive()
{
return
"Brrrrrrrrr";
}
}
We can create one of these cars then drive it and the noise it makes will be
"Brrrrrrrrr". Note the declaration of the Drive method as
public virtual.
A ferrari is indeed a car but the drive experience is different to that of the
ordinary runabout Honda Accord so a derived class of Ferrari would
override the Drive method thus:
class Ferrari
: Car
{
public override
string Drive()
{
return
"VVVRRRRROOOOMMMMMMM!!!!!!";
}
}
Note again how the declaration of the Drive method is now public override and
that the noise made by the car is "VVVRRRRROOOOMMMMMMM!!!!!!". Clearly, this is
not the same as the ordinary car.
Similarly, a Trebant car would have a different drive experience which you can
clearly see in the following example:
class Trebant
: Car
{
public override
string Drive()
{
return "Putt
putt cough putter";
}
}
You can chose for yourself which you would prefer.
Using these objects you would see the following:
Car c=new
Car();
Ferrari f=new
Ferrari();
Trebant t=new
Trebant();
Console.WriteLine(c.Drive());
Console.WriteLine(f.Drive());
Console.WriteLine(t.Drive());
On the console you would see:

To recap this section, a virtual method enables a
class derived from a base which was created at an earlier time to modify the
behaviour of that method by overriding.
Parametric Polymorphism
A class can modify the behaviour of a named method by creating a method of the
same name and return type but with different types in the method parameters.
When used in your code, the compiler differentiates between the methods
according to the parameters used.
class Porsche
: Car
{
public override
string Drive()
{
return base.Drive();
}
public string
Drive(bool RaceMode)
{
if (RaceMode)
return
"GGRRRRAAAAAAAWWWW-snick-GGGRRRAAAAAAAAAAWW-snick";
// snick is the gearchange
else
return base.Drive();
}
}
In the example above you see that the Porsche car has a race mode which can be
turned on by supplying a boolean parameter. This now enables us to do the
following:
Porsche p = new
Porsche();
Console.WriteLine(p.Drive());
Console.WriteLine(p.Drive(false));
Console.WriteLine(p.Drive(true));
In this example the Porche car drives normally if we just ask it to drive or to
drive with racemode off. Selecting race mode with a boolean true value however,
unleashes the beast.

Summary
Polymorphism, the third basic principle of object orientation enables us to
design classes that evolve their behaviour, even existing behaviours, as
required. The processes of overloading and overriding methods add the new
behaviour and the derived class has the opportunity to maintain the original
behaviour by calling the base class functionality.
|