Java Polymorphism | Polymorphism Java Example
If you look up the dictionary definition of Polymorphism, it is nothing but a condition to exist in different forms. Java Polymorphism is no different. To be available in different forms so as to help in reusing the same code over again is what Polymorphism is all about. So we leverage whatever code we have parked in our system, with 0 modification in the existing code.
Java Polymorphism
Think about it as building a house. Now you have already created a three room kitchen flat, but suddenly you realize you need an extra room dedicated entirely for your DC and Marvel Collectibles. What do you do? Break down the entire house and build it all over again? Or simply append a room on any one side of your flat without deteriorating the already built structure. The second one sounds reasonable, doesn’t it?
You reuse an existing code, you let your object take a different form, and you use the same bit all over again with different specifications. That’s how you can make the most of a code without going about changing it every now and then.
Polymorphism is a major OOPS concept that you should know about if you wish to be a Java pro. It is closely associated with Inheritance.
Don’t worry this chapter is entirely dedicated to it. Hopefully, by the time you reach the end, you would know everything there is to know about the concept of Java Polymorphism.
Polymorphic Test and Reference
First, let us address the elephant in the room. An object taking different forms so as to encourage code reuse is one of those typical examples of Java Polymorphism that we are going to see right away. But it isn’t just limited to that. We can achieve polymorphism by overriding and overloading a method as well.
When do you say a program is polymorphic? When your program passes more than one polymorphic test. Here’s one cool IS-A relationship test to find out whether your class is polymorphic or not.
Imagine there is a class called Superhero.
public class Superhero {}
And then another one which is your class, a subclass of this Superhero class:
public class Spiderman {}
The relationship your class goes something like this:
public class Spiderman extends Superhero {}
The IS-A Test
Now you gotta put your class against the polymorphic test:
Spiderman IS-A Superhero
Spiderman IS-A Spiderman
Spiderman IS-A Object
All these conditions hold true, meaning your class is a Polymorphic class. And any object of your class is going to make it a polymorphic object. But for a class to be a polymorphic class only two conditions need to be satisfied. With that logic, all Java objects are polymorphic by default since the last two statements of our test are always going to hold true for all objects.
Now taking the above Polymorphism Java example, the following object creation declarations are going to hold true at all times:
Spiderman spidey = new Spiderman(); Superhero sh = spidey; Object o = spidey;
The first one is going to be always true since it is its own object.
The second one is true since any object of subclass can be referenced by any instance of superclass. It is also popularly called as upcasting. Meaning any superclass can refer to any of its subclass object.
The opposite is however not true. Meaning downcasting is not allowed in Java. So if you are saying:
Spiderman spidey = new Superhero();
It wouldn’t be true since it would be downcasting.
The third one will always be true since Object is like the Big Daddy of all classes. A super, super class!
NOTE: All of the above reference variables spidey, sh and o are referring to the same object in the heap.
Polymorphism Java Example | Overriding
Now depending upon which method you are calling you can use their own respective reference variables.
For instance, if swings() and fly() are methods of Spiderman with fly() being a common method between Spiderman() and Superhero() classes,
all the possible calling methods would look something like this:
Now if you will run the above program you will get the following result:
Woohoo! Swoosh! Woohoo! Cling!
Virtual Method Invocation
In the Java Polymorphism example above, the method fly() has been called by reference variables of both types. However, which method to call is defined by whose object is instantiated. This type of method invocation is known as virtual method invocation and it happens during runtime.
The decision to which method is supposed to be called can only be identified at runtime and hence it is called late binding or dynamic binding. fly() is known as a virtual method. When you use the same method name in both subclass and superclass and then when method is called the subclass method overrides the superclass method, this phenomenon is known as method overriding. It is also known as runtime polymorphism.
Then there is another concept called method overloading.
It means you can use the same method name and distinguish it via its parameters. So calling a method by the same method name could be then distinguished by your JVM with the number of arguments it holds. The same thing we had seen in Constructor Overloading. Remember constructor is nothing but a method itself.
Overloading Example
Let’s take a look at our example and modify it a bit.
I am going to overload fly() method by providing it with different parameters like this:
Now when you call the method fly you have to specify on the basis of arguments which one do you wish to call. So if I wish to call fly(String s, int j) method, I need to provide a parameter that goes something like this:
Spiderman spidey = new Spiderman(); spidey.fly("What's the age of spiderman?", 24);
Using the above method we will get the result as:
What's the age of spiderman? 24
I am gonna call all of them one by one so you understand what’s going on:
Now if you will run the above program you will get the result as:
What's the age of spiderman? 24 Cling! 100 webs 43 jumps
What if you wish to call the superclass method of the same name?
You can simply make use of super keyword to do that. Read more about super keyword.
Use it in a method since it can’t be used in static context. So you put this inside a method, and let it call the superclass fly method:
super.fly();
That should do it.
The Final Say
So here’s what you should take in a nutshell from this relentless ranting:
- Overriding happens in runtime (dynamic binding) while overloading at compile time (static binding)
- Static methods can be overloaded meaning a class can have more than one static method of same name. Same holds true for private and final methods. All of these can’t be overridden.
- Overloading can be done in same class, but for overriding, you need to have a base and a child class. That’s obvious!
- Return types don’t matter in overloading. You can have any. An overriding method can have a more specific return type.
- Argument list should be different in overloading. It has to be same for overriding.
That’s it. I think we have captured Java polymorphism completely with that.
Stay tuned for more java tutorials.