What is Polymorphism?

Polymorphism is the property of something having many forms. A thing that has many forms is polymorphic. Appropriately, and perhaps confusingly, its meaning takes many forms, notably in computer science and biology. We’re interested in object-oriented programming languages so we’ll leave the other definitions to Wikipedia. In object-oriented languages there is more than one kind of polymorphism.

Polymorphic References and Overriding

As developers we’re interested in substitution (swapping one kind of object for another), the ability to plug in new components with new behaviour (creating new kinds of object) and to define general behaviour independently of the specific kind of object. That means we’re interested in having many forms of object; in computer science we use the specific term ‘type’. Objects themselves aren’t polymorphic as an object has only one type[1].

If objects don’t have many forms do classes? They define many types, so you might think so, but a class is its types, that is all of its subclasses and their subclasses and so on. We can’t talk about a class having many forms as it is all of its forms.

It’s the variable, the reference or pointer to the object, that is polymorphic. It can hold many forms of object. The class of the reference defines the kind of objects that it can hold.

Polymorphic references on their own wouldn’t quite get us what we want; on their own they would allow different kinds of object be substituted, but wouldn’t allow their behaviour to change. Overriding is what allows a subclass to replace methods on the superclass with their own behaviour. If you couldn’t override methods then all subclasses would behave in the same way. Overriding isn’t polymorphism, it’s just what makes it so useful.

Overloading

Methods can be polymorphic. There can be more than one form of a method on the same class. When a method is called the actual method invoked depends on the type of arguments supplied.

Generics

Parametric-polymorphism (generics in Java and templates in C++) allows us to have many forms of a particular class. This time it’s the classes that are polymorphic; there can be many forms of the class depending on the parameter type. For example in Java the Collection classes take a type parameter. This allows the collection to be defined independently of its contained objects. The developer is then able to create collections for a specific class of object and the compiler can check and enforce this. Without generics we’d either have to define a specific collection for each class, or have a collection that could take any kind of object, losing the benefits of type checking (the compiler wouldn’t be able to enforce, and therefore guarantee, the type of objects that the collection contains).


[1] An object of a specific type can belong to more than one class (interfaces, multiple inheritance); this is known as allomorphism.