Friday, 19 May 2017

Tutorial 16: Polymorphism, Upcasting and Downcasting



Polymorphism means many forms. It comes from the Greek words “poly” meaning many, and “morphe” meaning forms. If you are reading about polymorphism in Java for the first time, you might want to read the tutorial I created for inheritance. If you understand inheritance, then polymorphism will make a lot more sense.

So let’s say that we have a class Vehicle that is a child class of the class Machine. From the inheritance class we learnt that we tell Java that a class inherits from another by using the extends keyword. So in this case, we can say that class Vehicle extends Machine. This means that objects of the class Vehicle have the same protected member variables and public functions as the parent class in addition to its own member variables and functions.

Remember also that in the Inheritance tutorial, we used the phrase “is a” a lot. We said for example that because Vehicle is a child class of Machine, a Vehicle is a Machine. Then, we created a SportsCar class that is a child class of the Vehicle class, and this means that because the SportsCar class extends the Vehicle class, then by default, it also extends the Machine class.

Finally, remember that I told you in the Inheritance tutorial that every object in Java, every class you create and every class that exists in Java is a child class of the Object class. The Object class is the parent class of every class in Java. I also told you that the reason why we don’t go declaring that classes extend the Object class is because Java knows this, and doing so would be meaningless because the relationship is implicit.

It’s just the same thing in real life. Let’s look at a human being for example. The human being is a man. He is a father. He is a brother. He is a son. He is a grandson. He is a mammal. He is an uncle. He is an employee. He is a friend. He is a lover. He is a football fan. He is a tenant. He is a farmer.

Note however that because the man in the above example assumes all these roles, he is never all of them at the same time. What I mean is, he cannot carry out all his roles at the exact same time. So when he goes to work in the morning, he does so as an employee. When he goes to watch a game before going home, he is a football fan. When he goes to have a beer with his buddies, he is a friend. When he comes back home, he is a husband. At the end of the month, he is a tenant. When he works on his kitchen garden over the weekend, he is a farmer.

Here is where I want you to pay particular attention to what I’m about to say. The same logic we used in the above example applies in Java. If you have classes with a parent child relationship like the Machine and Vehicle classes, you can specify what Java should treat the object as at a certain time. So, I can create a new object of the class Vehicle and either say that it is a Vehicle or a Machine like this:

Vehicle vehicle1 = new Vehicle ();

The above statement tells Java to create an object of the type Vehicle known as vehicle1. Since Vehicle is a child class of the class Machine, it means that Vehicle objects have access to the protected member variables as well as the public functions of the Machine class as well as the functions and member variables of the Vehicle class itself.

However, Java also allows us to do this:

Machine machine1 = vehicle1;

Polymorphism allows us to use the child class where the parent class is expected.

So in the above statement, I am telling Java that I am creating a new Machine object. However, until I say otherwise, I want the new object to be treated as an object of the Vehicle class. Remember that the method that is called depends on the object that the variable is pointing to.

Upcasting

Remember that we are upcasting the object…not the variable.
Now what if I want to tell Java that, I now want vehicle1 to be treated as an object of the Machine class? What you do is create a new object of the type Machine like this:

Machine machine1 = vehicle1;

What this means is that the machine variable labeled Machine1 now points to the same object that the Vehicle variable vehicle1 is pointing to.

Downcasting

Remember that we are downcasting the object…not the variable.
Now what if I want to now tell Java that now, I want vehicle1 to be treated as an object of the Vehicle class? What you do is create a new object of the type Vehicle like this:

Vehicle vehicle2 = new Vehicle ();

Then, you pass the reference of vehicle2 to vehicle1 like this:

vehicle2 = (Vehicle) machine1;

In downcasting, Java wants you to confirm that you know what you are doing, and hence will require that you typecast the object as shown above. If you look at the example below with the screenshot, the concept will be clearer.

The Importance of Upcasting and Downcasting

You may be wondering: Okay so I understand the concept of polymorphism and the meaning of upcasting and downcasting. However, how is this important? You see, you may have two classes with a parent – child relationship. In these classes, you may the same functions with the same function names, but with different functionalities. For example, both the Machine and Vehicle classes have the methods known as start() and stop(). 

The start() method prints out “Starting the machine” in the Machine class but “Starting the vehicle” in the Vehicle class. The stop() method prints out “Stopping the machine” in the Machine class but “Stopping the vehicle” in the Vehicle class.

Upcasting and downcasting is important because it tells Java which functions and member variables you want the object to use at a specific time. In other words, it clears the confusion because Java knows for sure which start() or stop() method you are calling.

Why do we use the terms “Upcasting” and “Downcasting”?

In Java, if we were to represent the concept of inheritance using a diagram, this is how it would look:
 Figure 1: Graphical illustration of inheritance in Java. 

As you can see from Figure 1, the arrow in an inheritance relationship always points to the parent class. So, by telling Java to treat an object of the child class as an object of the parent class, we are moving in the direction of the arrow, hence the “up” in upcasting because we are moving upwards.

On the other hand, if we tell Java to treat an object of the parent class as an object of the child class, we are moving, according to the above diagram in a direction opposite to the inheritance arrow. Hence the “down” in downcasting. This means we are moving in an opposite direction to the inheritance arrow.

Example

Let us use a very simple example to see how polymorphism i.e. downcasting and upcasting works in Java. What we’ll do is create a class Machine and a class Vehicle. Vehicle will be the child class of Machine. In both classes, we will have two similar methods called start() and stop(). 

The start() method in the Machine class will print to the console: “Starting the machine.” However, the start() method in the Vehicle class will print to the console: “Starting the vehicle.”

The stop() method in the Machine class will print to the console: “Stopping the machine.” However, the stop() method in the Vehicle class will print to the console: “Stopping the vehicle.”

Then, we will create an object and upcast and downcast it, to see which function it calls.
Figure 2: A program demonstrating the concept of polymorphism i.e. upcasting and downcasting.

So, that’s about it with regards to polymorphism. If you haven’t understood this concept, you have probably not understood the tutorial on inheritance or you have not practiced enough. 

This concept took me weeks to understand. So there is no problem if you do not understand it right away. However, I would encourage you to read this tutorial again, think about what we’ve discussed, relate it to the examples I’ve given above and make sure you understand the tutorial on inheritance.

Some concepts may appear very difficult and daunting at first, but if you take the time to understand them, you will realize that at their core, they are very straightforward. The fact that they have big names such as “polymorphism”, “upcasting” and “downcasting” doesn’t make them any scarier. 

If you have any questions or comments, please drop them in the comments section below and I will address them as soon as possible.

Hope you enjoyed this tutorial as much as I enjoyed creating it. In the next tutorial, we learn about casting numbers, which is a lot more straightforward than upcasting and downcasting.

So until next time, stay safe.


No comments:

Post a Comment