Polymorphism lets you design a single interface (from a programming perspective, not a user interface) which is used to access different types of objects.
The advantage is being able to generalise your approach to designing classes, using methods/functions which behave differently, yet all have a single point of call.
in C++ polymorphism is enabled using a Base class pointer, which refers to any derived-class object. Using the base class pointer, you may invoke a method/function which will automagically determine the derived class type, and run the appropriate method.
In real-world terms, its somewhat analogous to driving a 4-wheeled motorised vehicle (If you know how to drive..) - the interface for any 4-wheeled motor vehicle is going to be the same regardless of what kind of 4-wheeled motor vehicle you're sat in (Clutch, Brake, Accelerator in the same place, steering wheel, gear stick, indicators etc). However, if you, the user of a motor vehicle, go from driving a car, to driving a van, you'll be driving under a completely different context. Although, from the driver's (the user's) perspective, its exactly the same, because all the controls do the same thing.
Polymorphism is expressed in C++ code using virtual functions. A program which expressed the Vehicle relationship described above might look something like this -
Code:
#include <iostream>
//Here is the "interface" class (an abstract base class)
class Vehicle
{
public:
//Here are the interface methods (virtual functions)
virtual void Accelerate() = 0 ;
virtual void Brake() = 0 ;
};
//A Car is-a Vehicle - it uses the Vehicle interface
class Car : public Vehicle
{
public:
//Car-specific behaviour
void Accelerate() { std::cout << "Car Accelerating\n"; }
void Brake() { std::cout << "Car Braking\n"; }
};
//A Bus is-a Vehicle - it uses the Vehicle interface
class Bus : public Vehicle
{
public:
//Bus-specific behaviour
void Accelerate() { std::cout << "Bus Accelerating\n"; }
void Brake() { std::cout << "Bus Braking\n"; }
};
int main()
{
//Begin with a driver driving a car.
Vehicle* Drivers_Interface = new Car;
//Run the car-specific behaviour through the common driver's interface
Drivers_Interface->Accelerate();
Drivers_Interface->Brake();
delete Drivers_Interface;
//Now move on to driving a bus
Drivers_Interface = new Bus;
//Run the bus-specific behaviour through the same interface as before
Drivers_Interface->Accelerate();
Drivers_Interface->Brake();
delete Drivers_Interface;
}
This on its own may seem a little useless (The example is rather contrived) But the potential benefits are when you want to hold a collection of different Derived class objects together using the same container, all objects which exhibit different behaviour. Typically C++ doesn't let you store different types of objects in a container - but you can use the base pointer (In this case, the Vehicle* ) as a basic reference point for all your different derived objects (Cars, Busses, etc) and store these reference points (the pointers) instead.
Using the base class pointer (Vehicle*), you have control over each object individually without needing to know its actual type - all you need to know about is the interface (the methods available in the Vehicle base class)
One way you may express a collection of Vehicle objects might look like this -
Code:
#include <vector>
int main()
{
std::vector<Vehicle*> my_vehicles;
my_vehicles.push_back( new Car );
my_vehicles.push_back( new Bus );
for( int i(0); i!=my_vehicles.size(); ++i)
{
my_vehicles.at(i)->Accelerate();
my_vehicles.at(i)->Brake();
}
}
Which displays the same output as the first program, but there's no obvious link in the for-loop from the method calls to what the outcome of each call may be (You, as the user of the Vehicle* vector have no idea what "kinds" of concrete vehicle objects you're storing).
I strongly suggest looking up polymorphism in your favourite book/tutorial/resource, since its a fairly large topic. This is really the tip of the iceberg.