Polymorphism

Submitted by coleen.yan@edd… on Mon, 04/22/2024 - 17:52
Sub Topics

You have had the opportunity to learn a bit about polymorphism in the introduction to OOP topic. Polymorphism is one of the four main ways that object-orientated programming is played out. If you need to refresh your memory, you can re-read that topic here.

Encapsulation Grouping together functions (called methods) and data (called properties) that are directly related to each other into one "Object". A fridge object contains data and functions relating to fridges.
Abstraction Hiding some of the methods and properties in an object to reduce complexity for the user. Why provide a complicated remote, if all the users needs to interact with is a play button?
Inheritance When creating a new class (serviced) based on an existing class (base), base class features are inherited, but derived class can also have its own features. An example may include having a new car that has inherited features from a previous.
Polymorphism

Poly (many) morphism (forms).
We can write a method that will take different forms depending on the type of the object we are referencing.

pourDrink() could produce one of five flavours here depending on which object its referencing.

Polymorphism

Polymorphism = Many forms
Poly means many
morph means form

Polymorphism is one of the object-oriented programming concepts that provide flexibility, consistency, and convenience through overloading or overriding. Polymorphism can be used when classes are related through inheritance, where a function behaves differently depending on the object that invokes it.

Polymorphism allows you to use the same function and have many different outcomes and it occurs when there is a hierarchy of classes that are related through inheritance. For example, if you have a program about animals and the function is to makeSound(), when the derived classes of Cat, Dog, Cow, and Horse are invoked the program would output each individual sound.

A diagram depicting polymorphism

Although there is only one function, it behaves differently under different circumstances. A function has many forms, hence we can achieve polymorphism.

Polymorphism can be understood better when you think on some real-world examples:

  1. A person can have more than one role and multiple responsibilities at work.
  2. Like the example in the opening image for the topic, a beer tap could produce twenty different drinks depending on the selection.
  3. A woman fulfils multiple roles each day. She may be a mother, a wife, a daughter-in-law, a sister, a daughter etc.
  4. A mobile phone is one device but can be used for multiple other tasks such as a radio, camera, calculator, message sender, torch, exercise tracker etc.

Watch as Saldina explains polymorphism in C++ programming (CodeBeauty, 2020).

Two types of polymorphism

  1. Compile-time polymorphism - In compile-time polymorphism a function is called at the time of program compilation. It’s known as early binding or static binding.
  2. Run time polymorphism. - Functions are called at the time of program execution. It’s known as late binding or dynamic binding.
A diagram depicting the types of polymorphism
Compile time polymorphism

You invoke the functions by matching the number and type of arguments. The information is present during compile time. This means the C++ compiler will select the right function at compile time.

Compilation time is the time when the source code is converted into an object code or executable code. Compile-time polymorphism is achieved through

  • function overloading
  • operator overloading.

Let’s take a look at both of these in a little more detail.

Function overloading

One function can perform many tasks. Function overloading happens when we have many functions with similar names but different arguments. The arguments can be different in terms of number, arguments, or type.

Function overloading can make a program easier to read by using the same name for the same action.

For example, a Shape (base class) having calcArea() can be overloaded in Square (derived class) and Circle (derived class). Both shapes Square and Circle have area to be calculated but their formula differs. (squareArea = a * a; and circleArea = 3.14 * r * r;)

Each redefinition of a function uses either different types of parameters or a different number of parameters. Here is an example of three different definitions for one function:

 

The compiler knows which version of the function to call based on which parameters are passed, as in the examples below. You will see that when the function is called with two integers, the compiler knows to use the version of the function which requires two integers.

Example 1:

Example 2:

Types of errors to watch for:

  • syntax errors
  • data mismatch, differing return types
  • typing mistakes
  • mismatching of parenthesis or curly braces
  • missing semicolon
  • if any of the functions are static member functions the function cannot be overloaded
  • function declarations that seem different, but are actually the same for example, *p is the same as p[], or where one of the functions is a pointer to the other.

Read more about function overloading in C++ (Geeks for Geeks, 2021) to learn about the various relationships and dependencies.

Learn about functions that cannot be overloaded in C++ (Geeks for Geeks, 2018).

Before we head into Operator Overloading, learn about copy constructors in C++ (Geeks for Geeks, 2022).

One of the main benefits of function overloading is providing flexibility for the user, allowing them to enter different formats, which the program can interpret appropriately.

Operator overload

C++ provides the opportunity to overload operators such as + or * to redefine what they do. We know + is the addition operator whose task it is to add two operands, however we can also make the operator concatenate two strings. So, when + is placed between integer operands it adds them, and when placed between string operands, it concatenates them.

 

Would create an output of z = 8, because the + operator used with two integers will add them together.

 

Would create an output of c = "New Zealand", because the + operator used with two strings will concatenate them.

Syntax

The syntax for operator overloading is as follows:

returnType operatorOperatorSymbol(parameters);

Example

The following example sees the + overloaded. The operator + is used here to perform addition of two imaginary or complex numbers.

Watch Bucky demonstrate the use of Operator Overloading in

Buckys C++ Programming Tutorials – 50 – Operator Overloading

(thenewboston, 2011)

and

Buckys C++ Programming Tutorials – 51 – More on Operator Overloading

(thenewboston, 2011)

Polymorphism Operator Overloading

Can be overloaded
+ - * / % ^
& | ~ ! , +=
< > <= >= ++ --
<< >> == != && ||
+= -= /= %= ^= &=
|= *= <<= >>= [] ()
-> ->* NEW NEW[] DELETE DELETE[]
Can not be overloaded
:: .* . ?:

You can find a more expanded explanation with good examples of how to overload operators at Geeks for Geeks.

Run time polymorphism

Run time is the time when the program starts running after compilation. The other ways polymorphism can be achieved is by function overriding and virtual functions. It provides slow execution as it happens at the program run time.

For more information, read about virtual functions and runtime polymorphism in C++.

Function Overriding

Function overriding occurs when a derived class has a definition for one of the member functions of a base class. The base class is said to be redefined by the derived class because it’s given a new definition, in other words the base class member function is overridden by the derived class function definition.

Types of errors to watch for:

  • Division by zero
  • Memory leaks

It can be easy to get function overriding confused with function overloading.

  • With function overloading, we are talking about more than one function by the same name in one class. The parameters that are passed are what determines which version is called.
  • With function overriding, a function definition in the derived class overrides the definition given for the function of the same name in the base class.

The following example will illustrate the difference clearly.

Virtual Function

Using virtual function is another way of implementing runtime polymorphism. It’s a special function defined in the base class and redefined in the derived class but declared using the virtual keyword. The keyword should precede the declaration of the function in the base class. The return type may be int, float, or void.

The virtual function helps to tell the compiler to perform late (or dynamic) binding on the function. If the function has no definition, we call in the Pure virtual function (=0) which is also known as the ‘do nothing function’. This happens in the base class with no definition.

Watch Bucky explain the use of virtual functions in polymorphism (thenewboston, 2011) in the following video

Revision

Read an article on Guru999.com to get an in-depth understanding of polymorphism along with examples and line-by-line explanations of program code showing the stages at which polymorphism occurs.

Module Linking
Main Topic Image
A programmer intently working at their work station, by the window.
Is Study Guide?
Off
Is Assessment Consultation?
Off