4. Polymorphism

In this chapter you will learn:
  • What polymorphism is
  • What the different types of polymorphism are and how they are used
  • What virtual methods are and how they are used
  • How to create object-oriented programs with polymorphism

Polymorphism

Object-oriented languages allow for multiple methods with different implementations to use the same method name. This is known as polymorphism and can come in one of two forms: overriding (which replaces one method with a new method of the same name) or overloading (which allows multiple methods with the same name to exist at the same time).

Polymorphism is important for object-oriented programming because it means that the ‘same’ method can have multiple implementations depending on how it is being used, instead of declaring methods with different names for each different implementation. This is useful because it allows different parts of a program to use a method without needing to know which specific implementation is required, allowing for better encapsulation of the program.

Overriding

One of the most common uses for polymorphism is to allow a child class to ‘overwrite’ a method in its parent class. This is an example of overriding.

Overriding simply replaces one implementation of a method with another. For example, consider the following parent and child classes:

Pseudocode

The SlowWorm class inherits every method included in the Lizard class by default. This includes the constructor method new. Because a SlowWorm doesn’t have any legs, it cannot use the same new method as its parent class, Lizard; however, most object-oriented programming languages require constructors to have a particular name (in this case ‘new’), and so the only way a constructor can be defined for the SlowWorm class is by allowing it to override the new method of its parent class, Lizard.

The constructor is not the only method that can be overridden. Any method that can be overridden in a child class is known as a virtual method. Virtual methods are declared differently depending on the programming language; for example, methods in Java are virtual by default and are made non-virtual by including the ‘final’ keyword (which prevents child classes from overriding it), whereas in C# the ‘virtual’ keyword is required to allow the method to be overridden.

Pseudocode

This program overrides the virtual method move in the Lizard class. The inclusion of the ‘final’ keyword in the definition for the move method in the SlowWorm class means that if another class were to inherit from SlowWorm it would not be able to override move because it is defined as a non-virtual method.

Overloading

The other type of polymorphism is overloading. Overloading allows multiple methods that require different parameters to use the same name. For example, you may want to make some values optional when instantiating an object:

Pseudocode

The Cat class is defined with two different constructors. The constructor to be used is selected at runtime depending on the arguments that are passed to it; so, when mia is instantiated, the first constructor is used (because one argument is given), but when percy is instantiated the second constructor is used (because two arguments are given).

Unlike overriding, which allows one method to act in place of another, overloading creates completely different methods which simply share a name, so overloading is not considered to be ‘true’ polymorphism.

Python Note:

Python doesn’t use multiple method definitions for overloading, but instead allows for the use of default parameter values to make certain parameters optional. So, instead of writing a program as:

Pseudocode

It would be written as:

This sets the default value of the legs parameter to 4, allowing the method to be called with either one argument (which will use the default value of legs) or two arguments (which will override the default value of legs). Parameters with default values should be declared after all parameters which require values. For example:

This method would throw an error because if only one argument is passed it is not clear whetherthat argument should be used for the first non-default parameter or for the first parameter (this can become an issue as methods start using multiple parameters with default values).

As Python uses duck typing (meaning that the type of a variable is not important as long as any operations used on the variable are valid), method overloading is not required to allow a method to accept different types of parameter (i.e. the constructors above will work no matter if the argument given for age is a number, string or other data type).