Inheritance and Polymorphism are different things so comparing them isn't very easy.
Inheritance is when a class gets methods and stuff from its base class.
1 2 3 4 5 6 7 8 9
|
class Cat
{
public:
string getNoise() { return "MEOW"; }
}
class SmallCat : public Cat
{
}
|
In my example above SmallCat will also have a getNoise() method exactly the same as its base class, this is inherited. you dont need to specify it, your class will automatically get everything the base class has.
Polymorphism is a special kind of overriding. Whats overriding?
1 2 3 4 5
|
class BigCat : public Cat
{
public:
string getNoise() { return "ROAR"; }
}
|
Now BigCat still has a getNoise() method but it contains different code to the one in the base class, this is overriding. the return type, name, and parameters must be the same, only the code can be different.
1 2 3 4
|
SmallCat kitty;
BigCat simba;
cout << kitty.getNoise(); // echo "MEOW"
cout << simba.getNoise(); // echo "ROAR"
|
Polymorphism is a solution to a problem, if you dont have the problem, then you dont need to solution. The problem is i want a method that i can give a cat to and it doesnt care what type of cat it gets.
1 2 3 4
|
void ListenToCat(Cat* pCat)
{
cout << pCat->getNoise();
}
|
1 2 3 4
|
SmallCat kitty;
BigCat simba;
ListenToCat(&kitty); // echo "MEOW"
ListenToCat(&simba); // echo "MEOW"!!!!!
|
Why didn't ListenToCat(&simba) "ROAR"?
Its because ListenToCat() doesn't know you passed in a BigCat object! it thinks it's a Cat object (parameter type)
We need a way to call BigCat's overridden getNoise() even if we have a Cat*.
We do this by declaring getNoise() as virtual.
1 2 3 4 5
|
class Cat
{
public:
virtual string getNoise() { return "MEOW"; }
}
|
1 2 3 4 5
|
class BigCat : public Cat
{
public:
virtual string getNoise() { return "ROAR"; }
}
|
Now when ListenToCat() calls getNoise() it will get the one from the object you passed instead of the class the parameter was declared as.
1 2 3 4
|
SmallCat kitty;
BigCat simba;
ListenToCat(&kitty); // echo "MEOW"
ListenToCat(&simba); // echo "ROAR"!!!!!
|
This concept of "virtualising" functions is Polymorphism. It lets us create as many classes derived from Cat as we like and ListenToCat() can work with them all by using Cat*.
We can enforce this polymorphism by making Cat::getNoise() "pure virtual" this means all derived classes MUST override getNoise() because the base class doesn't have any code.
1 2 3 4 5
|
class Cat
{
public:
virtual string getNoise() = 0; // = 0 pure virtual
}
|
1 2 3 4 5
|
class BigCat : public Cat
{
public:
virtual string getNoise() { return "ROAR"; }
}
|
As i said, pure virtual forces the override, so we must also give SmallCat an override or it wont compile, there is no getNoise() code to inherit!
1 2 3 4 5
|
class SmallCat
{
public:
virtual string getNoise() { return "MEOW"; }
}
|
With this in mind, Bdanielz example above is not polymorphism, because he always uses the Dog and Cat objects, never using the Mammal to polymorph the different animals. Therefore his example is one of "overriding" and the virtual keywords are moot.