Human language is often murky, so I will stick to C++-specific terms here.
A
polymorphic object class is one that can change to be what you think it is.
That is kind of broad, so let us look at a real-world example that we use all the time in C++:
iostreams.
1 2 3 4 5 6
|
#include <iostream>
int main()
{
std::cout << "Hello world!\n";
}
|
In this example we expect the words
Hello world!
to appear on the terminal. That is because
std::cout
is a
specialization of a
std::ostream
that knows how to talk to the terminal.
But what if I wanted to write to a file?
1 2 3 4 5 6 7
|
#include <fstream>
int main()
{
std::ofstream fout( "hello.txt" );
fout << "Hello world!\n";
}
|
The fact that the code on line 6 looks nearly identical to the code on line 5 above is no coincidence. That is because both
std::cout
and
fout
are polymorphic instances of (or specializations of) a
std::ostream
.
We can use that to our advantage. Here we have a function that takes
any kind of ostream:
1 2 3 4 5 6 7
|
#include <fstream>
#include <iostream>
void say_hello( std::ostream& outs )
{
outs << "Hello world!\n";
}
|
Because both cout and fout are a kind of ostream, we can use the function for either:
9 10 11 12 13 14 15
|
int main()
{
say_hello( std::cout );
std::ofstream fout( "hello.txt" );
say_hello( fout );
}
|
The reality is that cout and fout are very different underneath. One speaks to the terminal. The other speaks to a file. But BOTH are a kind of output stream and are, from our perspective when using them, the same. We can call them both “ostream”, but they know what they really are, and do the Right Thing™ then asked to write text to their output.
This is the power of polymorphism.
Runtime Polymorphism and Method Overriding are not synonyms, but they are related.
Method Overriding is the term for specializing the behavior of an object based its type:
• ofstream has a function named operator<< that sends output to a file
• std::cout has a
different function named operator<< that sends output to the terminal
And so on.
Runtime Polymorphism is the term for
actively choosing the correct function to use, based on the object’s true type.
We have seen this in the example above. The say_hello() function has, as argument, an ostream. That is all it knows about it.
When say_hello() says
outs << "Hello world!";
, it doesn’t know where the text actually goes.
But
fout
knows what it really is, and chooses the correct operator<<() function to write text.
• if fout is an ofstream, use ofstream::operator<<().
• if fout is cout, use cout.operator<<()
And so on.
The choice based on the actual type (“polymorphism”) happens when the function is called (at “runtime”).
This is a
very brief overview. You should start googling around object orientation and abstraction, encapsulation, inheritance, and polymorphism. And, despite what morons say, Wikipedia is an excellent place to start reading.
Hope this helps.