Principles of Object Oriented Programming — Part Three: Polymorphism
By: The Inquisitive Dev
Tags: Java, Coding, Object Oriented

Now, polymorphism sounds a little scary but if you look it up in the dictionary, all it means is, “the condition of occuring in several different forms.” In the context of programming, it describes methods that have the same name, but perform difference logic. As with the other posts in this series, I will use Java for my code examples.

In Java, polymorphism can take on two types:

Static

Dynamic

Static Polymorphism

This is where methods in the same class can have the same name but different parameter variations. In Java, static polymorphism is achieved with method overloading. The parameters or input data into the method can vary in 3 ways:

The number of parameters

The data types of parameter

The order that the parameters are declared (not recommended as it can be confusing)

Together the method name and the declared parameters are known as the method signature. Any of the above variations result in a different method signature, which will allow the compiler to wire up the correct method body at compile time. This is known as static or early binding, as it occurs at compile time, before the program runs. As a result, program execution is much faster.

As a side note, any static, final or private methods are always statically bound, as the compiler knows they cannot be overridden at runtime.

Dynamic Polymorphism

Java also supports dynamic polymorphism. It is achieved through method overriding, not to be confused with overloading.

I already covered overriding in my last post on inheritance. But to quickly recap, if a child class and a parent class both have a method with the same name, the child class’s method takes precedence. In this scenario, the polymorphic method exists in multiple classes (child and parent) and has the same signature but different functionality.

The variation of method body called will depend on the type of object instantiated. The compiler will not have this information at compile time, it will be worked out at runtime.

The example above demonstrates how the move() method version called depends on the object being instantiated. As a general rule, unless the method is labelled as static, final or private, the method called will belong the object type (right side of the equals sign) rather than the reference type (left side of the equals sign).

In addition, because method binding occurs at runtime, program execution using dynamic binding will be slower than static binding. The advantage of dynamic binding is the added flexibility it gives you. Below is a typical example of where this flexibility can help you.

We might declare a new ArrayList like below.

We use a reference type of List and an object type of ArrayList. Later, we decide that a LinkedList object is better suited to the task. Because ArrayList and LinkedList both subclass List, we can easily swap out the object type to the LinkedList object without breaking the rest of our code.

Summary

Below is a table summarising the difference between static and dynamic polymorphism.

Method overloading allows methods that perform similar/related functions to share the same name. Overloading can also be applied to class constructors, allowing you to instantiate different but related objects based on what parameters are available at the time. Method overriding allows classes to share generalised behaviour, reducing code duplication. It also allows sub classes to specialise where required.

Subscribe

If you found this article useful I’d love you to become a subscriber to my blog. I will be dropping articles regularly on all things coding. Knowing I have people reading would mean the world.

As always, thanks for reading!