Examples of polymorphism in Java and C++

Polymorphism is a powerful tool that we can use to create clearer, simpler and maintainable code. In this article, I show examples of polymorphism in several languages.

Sometimes beginners make some mistakes when learning programming. A common mistake is to learn a specific programming language rather than the fundamentals of programming or the technique they are using. I want to show you with examples, why is important to learn the fundamentals to be a good programmer.

What is polymorphism in programming?

A prerequisite to understanding polymorphism is inheritance. If you still don’t know what inheritance is and how to use it you can read this post.

Polymorphism is a very important and powerful tool that we have when we use the Object-Oriented Programming Paradigm.

For us to study polymorphism we first must understand two concepts:

  1. Static type: when we declare a variable, we have to specify a type, that type is called the static type.
  2. Dynamic type: when we create an instance of a class, the type of that class is called the dynamic type.

A Java example:

List myList<String> = new ArrayList<String>();

In this case, the class List is the static type (the type used in the definition) and the class ArrayList is the dynamic type (the type used to create the instance). Most of the time in our code the static type and the dynamic type of a variable is the same. But that is when we don’t have polymorphism in our code.

We can write this kind of code only because ArrayList inherits from List. In other words, List is the base class and ArrayList is the derived class.

Polymorphism is the ability of an object to behave according to the dynamic type. Also, the dynamic type must be different from the static type.

What are the conditions that must occur for us to have polymorphism? You will find the answer in the next section.

When to use polymorphism?

A common situation we have to use polymorphism occurs when:

  • We have a class hierarchy with one base class and several child/derived classes. 
  • At least one derived class overrides a method in the base class, and we use that method.
  • We have an object with a dynamic type different than the static type.
  • The method that we override is virtual. Some programming languages implicitly define methods as virtual.

The main advantage of polymorphism is that we can invoke a (virtual) method that is overridden by some of the derived classes, without checking the dynamic type of the object.

The use of polymorphism will avoid you the use of several “if’s”. It will make your code clearer and easy to maintain.

Now that you have the basic reasoning behind polymorphism, let’s see some examples in several programming languages.

Example of polymorphism in Java

class StaffMember{
    protected String name;
    protected float salary;

    public StaffMember(String name, float salary){
        this.name = name;
        this.salary = salary;
    }
    
    public float getBonus(){
        return (float) (this.salary + this.salary * 0.10);
    }
}

class ManagementStaff extends StaffMember{
    private String jobPosition;

    public ManagementStaff(String name, float salary, String jobPosition) {
        super(name, salary) ;
        this.jobPosition = jobPosition;
    }
    @Override
    public float getBonus(){
        return (float) (this.salary + this.salary * 0.15); 
    }
}


class ConsoleApp {
    public static void main(String[] args) throws Exception {
        StaffMember staff[] = new StaffMember[2];
      
        
        staff[0] = new StaffMember("Jane Doe", 100);
        staff[1] = new ManagementStaff("John Doe", 100, "Supervisor");
        
        System.out.println("staff 1 bonus: " + staff[0].getBonus());
        System.out.println("staff 2 bonus: " + staff[1].getBonus());
    }
}

In this case, there is polymorphism. The reason is simple:

  • The variables are references. In Java, all variables (objects, except the ones that the type is a primitive type) are references.
  • The static type is different than the dynamic type. 
  • The overridden method is virtual. In Java, when a method is overridden is explicitly virtual.

Example of polymorphism in C++

As you will see in this section, to have polymorphism in C++ we have to declare the method as virtual.

#include <string>
#include <iostream>
using namespace std;

class StaffMember{
    protected:
        std::string name;
        float salary;
    public:
        StaffMember(){

        }
        StaffMember(string name, float salary){
            this->name = name;
            this->salary = salary;
        }
        float getBonus(){
            return (float) (salary + salary * 0.10);
        }
        string printName(){
        return name;
    }
};

class ManagementStaff: public StaffMember{
    private: 
        string jobPosition;

    public:
     ManagementStaff(string name, float salary, string jobPosition): StaffMember(name, salary) {
        this->jobPosition = jobPosition;
    };
   
   float getBonus(){
        return (float) (salary + salary * 0.15); 
    }
    
};


int main() {
        StaffMember* staff[2]; // = new StaffMember[2];
      
        
        staff[0] = new StaffMember("Jane Doe", 100);
        staff[1] = new  ManagementStaff("John Doe", 100, "Supervisor");
        
        cout << "staff 1 bonus: " << "\n";
        cout<< staff[0]->getBonus() << "\n";
        cout << "staff 2 bonus: " << "\n";
        cout<< staff[1]->getBonus() << "\n";
        

        StaffMember *mStaff = new  ManagementStaff("Elle", 100, "HoD");
        cout << "Last staff: " << mStaff->getBonus() << "\n";

        return 0;
};

If you execute the code above, the result will be as follows:

output example of polymorphism in C++

As you can see above, staff 2 is a management staff but the bonus is calculated as staff (10% extra).

However, the bonus for the last staff member is right.

Why is this happening?

This issue has a simple explanation. There is no polymorphism happening in the example.

There is no polymorphism when using the array “staffs” because we didn’t tell the compiler that method “getBonus” will be overridden in derived classes. We can fix this by declaring the method in the base class as virtual.

In the second case, there is no inheritance because the variable mStaff is not a reference. Also, the dynamic type is the same as the static type.

If we want to have polymorphism in this last case, we have to do the following:

  • First, make the method “getBonus” in the base class virtual.
  • Second: make the variable mStaff to hold a reference:
StaffMember *mStaff = new  ManagementStaff("Elle", 100, "HoD");
cout << "Last staff: " << mStaff->getBonus() << "\n";

Conclusions

As a summary, it is always important to know the fundamentals, what is polymorphism? When do you need it? And how to implement it.

For you to have polymorphism the following must happens:

  • We have a class hierarchy with one base class and several child/derived classes. 
  • At least one derived class overrides a method in the base class, and we use that method.
  • We have an object with a dynamic type different than the static type.
  • Virtual methods are defined.

Programming languages are created in different ways. Some are more Object-Oriented than others. Some make life easier for programmers implementing concepts as a part of the language itself (like virtual methods).

If you learn the programming fundamentals, you will get a better and deeper understanding. Therefore, you will learn programming languages easily. 

Don’t forget that algorithms are part of the fundamentals of programming.

You can also find here the object-oriented programming principles. They are also part of the fundamentals.

I hope now you have a better understanding of polymorphism. You can now apply it in different programming languages. At least on the ones explained in this article.

H@appy coding!!