Skip to Content

C++: Polymorphism

NOTE: Still being created…

Recall: Three main OO ideas:

Object Orientation is the combination of three main ideas:

  • Encapsulation: this means putting things together to make it look like a whole and to hide the internal things from external inspectors outside.
  • Inheritance: this means that some types can be subtypes of other things and inherit their features. For this, always think of the phrase “is-a”. For example, a bear is-a mammal. Bears inherit features of mammals (all mammals have hair; bears have hair).
  • Polymorphism: this means that things in your program can act differently based on the context. (Greek “poly” means many, “morph” means form; so the word means “many forms”)

Polymorphism (Subtype)

In programming languages, there are actually (at least) three types of polymorphism: subtype, parametric, and ad-hoc polymorphism. When discussing Object-Oriented ideas, we are generally focused on subtype polymorphism. This page will address the other two down at the bottom of the page.

Recall that inheritance is an is-a relationship: an object of a subclass is an object of the parent class(es). With inheritance, this means that all of the attributes and operations of the parent class become included in the subclass, and thus the object has access to all of these (actually, is in part made up of these).

Thus, the object can be viewed as having has multiple (poly) kinds (morphs).

But polymorphism in programming means that we can actually take advantage of this idea in our code. We can pass this object (or references to it) as any of these class kinds, and we can write code that manipulates the object as any of these kinds. Furthermore, the object retains its true type and identity throughout all of this.

Suppose we had an abstract Mammal parent class and the subclasses of Dog, Elephant, and Lion. Imagine we had the following code:

void Zoo::makeNoises(vector<Mammal*>& animals)
{
    for (Mammal* animal : animals) {
        animal->makeNoise();
    }
}

Our actual vector is populated with pointers to objects of the subclasses, because Mammal is abstract. But our code does not know anything about these subclasses! It is written only with knowledge of the parent class. Yet as we iterate through the vector, this code will invoke makeNoise() on each object, and assuming that each subclass did an override and has its own makeNoise() method, this code will invoke each of the subclass’s method properly!

That’s polymorphism! The objects can be passed and treated as objects of their parent classes, and code that is written generically for some parent class can use objects of the subclasses, and if the subclasses have unique behavior, the code will use it. This is the heart of subtype polymorphism.

Inheritance and polymorphism are great tools for developing generic code and for code reuse, but they are very powerful and so need to be used carefully and with a lot of deep thought about class design and inheritance design. When done right, it is great!

Parametric Polymorphism

Simply put this is what Java generics and C++ templates do. It is another way that code can be reused in many (poly) different ways (morphs). The idea with Java generics and C++ templates is that you want to create (usually) some sort of collection and specify generic operations on the collection, and you want the type of objects in the collection to be specific, but you want the capability over lots of types of objects.

So the type of object in the collection needs to be a parameter to the code—hence parametric polymorphism. This makes the code a template (hence, the C++ use of template) where the code is instantiated by copying the object type into the code. This most often occurs in collection-type classes, but can occur elsewhere. Both Java and C++ use the angle-bracket syntax to specify the type parameter to the template.

Java has the Java Collections classes, while C++ has the Standard Template Library (STL). Indeed the vector class that we have been using is from the STL.

Ad-Hoc Polymorphism

Ad-hoc is a term we use when we don’t know what to call something, or don’t have a good, clear reason for it. In some sense it is a catch-all for anything that looks like polymorphism in code, but isn’t subtype or parametric polymorphism.

In Java and C++, ad-hoc polymorphism comes in the form of function/method overloading. In both languages, we can define functions that have the same name, but take different arguments. In C++ this goes even further in that we can define new meanings of operators.

Thus, the method name has multiple (poly) meanings (morphs); depending on the arguments used, a different method body will be invoked.

Resources

Far too many resources on the web, but Wikipedia:Polymorphism is a good start.