Polymorphism in Java

Introduction

The ability of an object to behave differently in different situations is called Polymorphism. This concept is core to object oriented programmer and key to programming in Java. There are two types of polymorphism prevalent in Java; Static Polymorphism and Dynamic Polymorphism. As a Java developer, you will routinely use each type of polymorphism.

Types of Polymorphism

Static Polymorphism

In a Java program, it is possible to have two or more methods in the same class having the same name but with different argument lists. The argument lists can differ in the number of parameters, data type of parameters and the sequence of data type of parameters. This is called static polymorphism. It is also commonly known as method overloading. The correct method to be called is selected on the basis of the argument list. Note that the return type of the method has no bearing on it’s behavior in terms of static polymorphism.

The class below is an example of Static Polymorphism.

In this example, three methods with the name of ‘test’ have been defined. Each differs in its argument lists. In the first method, only one parameter is present having data type ‘int’. In the second method, two parameters are present, both with data types ‘int’. And in the third method, there is only one parameter with data type ‘double’. The name of all the three methods is same, but their argument lists are different. This is what makes them overloaded methods.

Static Polymorphism in Action

We can write a unit test for our example class to observe Static Polymorphism at work. In our test, each method is called with the proper argument list.

If we run our test, we can observe the following results:

Just like methods, constructors can also be overloaded. We generally have two types of constructors, default constructor and parametrized constructor. Which among the default constructor or the parametrized constructor will get invoked, depends on the type of constructor which is invoked during the object creation. We can use the this() invocation to invoke one constructor from another one. We just need to pass the proper parameters for invoking the appropriate constructor using the this() invocation.

Static Polymorphism is often used when you have a list of parameters for a method or constructor call and you wish to default some of the values. You can use Static Polymorphism to provide alternate implementations of methods or constructors which supply default values for the optional parameters.

Dynamic Polymorphism

Dynamic polymorphism is a key concept in Object Oriented programming. If you wish to become an effective Java programmer, you will need to have a firm understanding of Dynamic Polymorphism. Consider the following class:

This is a simple class for the purposes of our demonstration. In Polymorphism terms we will be referring to this class as a base class. Its a class you expect to extend with other classes. If you expect this class to never be instantiated, or if it should never be instantiated, it is a good programming practice to make the class abstract, so it cannot be used directly.

We implement dynamic polymorphism in Java by extending classes. Consider this example:

Here we have a Car  object which extends our Vehicle  class. We are free to add properties to our extended class as we have done with the numberOfWheels  property.

In this example, we are also overriding the vehcileName  method of the base class. While you are not required to, in this example, we are using the @Override  annotation on the vehicleName  method. This tells the Java compiler you wish to override the method of the base class. If the signature of the method does not match a signature of a method on the base class a compiler error will be thrown. This helps prevent you from accidentally introducing a new method, rather than overriding the method of the base class. It also aids in the readability of your source code for other programmers. Your intention of overriding a method of the base class is clear. While you are not required to use the @Override  annotation, it is considered a best practice to use.

Through polymorphism, your base class can be extended to handle other use cases.

In the example above, we’ve extended our base Vehicle class with a Motorcycle class. Following the concepts of Object Oriented Programming, using polymorphism, we could have additional classes things such as Boat, Plane, Bicycle, Truck, Armored Tank. While each of our use cases are different, each is technically a vehicle. This gets us to the classic Object Oriented programming “Is a” test.

  • A Car  is a Vehicle .
  • A Motorcycle  is a Vehicle .
  • A Boat  is a Vehicle .
  • A Armored Tank  is a Vehicle .

You are not limited to extending a class just once. Consider this example:

Here we have a Corvette class which extends our Car class, which extends our Vehicle class.

A Corvette  is a Car .

A Car  is a Vehicle .

It is common when using polymorphism in object oriented programming for your extended classes to become more and more specialized. In our Corvette  example, you can see how our new class has additional properties and methods specific to the Corvette  object. Consider how your class would change if it was a Plane  or a Boat  object.

Dynamic Polymorphism In Action

A child class object can be assigned to a parent class reference. The syntax for the same has been given below,
Vehicle vehicle = new Corvette();

We can write a unit test using JUnit to demonstrate this with our examples so far.

The output of this test is:

In our test, we used Java generics to create a list of Vehicles, then added an instance of each other extended types we have been working with. Our method call on vehicleName worked because each object in the list is a Vehicle.

One caveat you need to be aware of is this is not a two way street. Consider:

Do you think this will work?

No, it will not. This fails the ‘Is a’ test. While a Corvette is a Vehicle, a Vehicle is not a Corvette.

Remember that your extended classes will inherit from your base classes. But if you declare your variable to use the base type, even if you assign the extended type to your variable, the extended properties and methods will not be available. This is the nature of a strongly typed language like Java.

Naturally, you can use type casting to work around this:

But use caution with type casting. In this example, if the vehicle was not an instance of a Corvette  object, your program would fail on a runtime error.

Conclusion

As you can see in these examples, polymorphism is a very powerful concept in Object Oriented programming. It gives you tremendous flexibility in composing your code. Like any tool in programming, polymorphism is something that can be misused or overused. However, once you master polymorphism, it will bring a degree of elegance to your code. Your code will be easily read by others, and easy to maintain as your code evolves over time.

Share

You May Also Like

2 comments on “Polymorphism in Java

  1. Polymorphism is one of the four fundamental OOP concepts. The other three being –
    1- Inheritance
    2- Encapsulation
    3- Abstraction

Leave a Reply