What is Upcasting and Downcasting in Java
- Details
- Written by Nam Ha Minh
- Last Updated on 25 August 2019   |   Print Email
Perhaps in your daily Java coding, you see (and use) upcasting and downcasting occasionally. You may hear the terms ‘casting’, ‘upcasting’, ‘downcasting’ from someone or somewhere, and you may be confused about them.
As you read on, you will realize that upcasting and downcasting are really simple.
Before we go into the details, suppose that we have the following class hierarchy:
Mammal > Animal > Dog, Cat
Mammal is the super interface:
public interface Mammal { public void eat(); public void move(); public void sleep(); }
Animal is the abstract class:
public abstract class Animal implements Mammal { public void eat() { System.out.println("Eating..."); } public void move() { System.out.println("Moving..."); } public void sleep() { System.out.println("Sleeping..."); } }
Dog and Cat are the two concrete sub classes:
public class Dog extends Animal { public void bark() { System.out.println("Gow gow!"); } public void eat() { System.out.println("Dog is eating..."); } } public class Cat extends Animal { public void meow() { System.out.println("Meow Meow!"); } }
1. What is Upcasting in Java?
Upcasting is casting a subtype to a supertype, upward to the inheritance tree. Let’s see an example:
Dog dog = new Dog(); Animal anim = (Animal) dog; anim.eat();
Here, we cast the Dog type to the Animal type. Because Animal is the supertype of Dog, this casting is called upcasting.
Note that the actual object type does not change because of casting. The Dog object is still a Dog object. Only the reference type gets changed. Hence the above code produces the following output:
Dog is eating…
Upcasting is always safe, as we treat a type to a more general one. In the above example, an Animal has all behaviors of a Dog.
This is also another example of upcasting:
Mammal mam = new Cat(); Animal anim = new Dog();
2. Why is Upcasting in Java?
Generally, upcasting is not necessary. However, we need upcasting when we want to write general code that deals with only the supertype. Consider the following class:
public class AnimalTrainer { public void teach(Animal anim) { anim.move(); anim.eat(); } }
Here, the teach() method can accept any object which is subtype of Animal. So objects of type Dog and Cat will be upcasted to Animal when they are passed into this method:
Dog dog = new Dog(); Cat cat = new Cat(); AnimalTrainer trainer = new AnimalTrainer(); trainer.teach(dog); trainer.teach(cat);
3. What is Downcasting in Java?
Downcasting is casting to a subtype, downward to the inheritance tree. Let’s see an example:
Animal anim = new Cat(); Cat cat = (Cat) anim;
Here, we cast the Animal type to the Cat type. As Cat is subclass of Animal, this casting is called downcasting.
Unlike upcasting, downcasting can fail if the actual object type is not the target object type. For example:
Animal anim = new Cat(); Dog dog = (Dog) anim;
This will throw a ClassCastException because the actual object type is Cat. And a Cat is not a Dog so we cannot cast it to a Dog.
The Java language provides the instanceof keyword to check type of an object before casting. For example:
if (anim instanceof Cat) { Cat cat = (Cat) anim; cat.meow(); } else if (anim instanceof Dog) { Dog dog = (Dog) anim; dog.bark(); }
So if you are not sure about the original object type, use the instanceof operator to check the type before casting. This eliminates the risk of a ClassCastException thrown.
4. Why is Downcasting in Java?
Downcasting is used more frequently than upcasting. Use downcasting when we want to access specific behaviors of a subtype.
Consider the following example:
public class AnimalTrainer { public void teach(Animal anim) { // do animal-things anim.move(); anim.eat(); // if there's a dog, tell it barks if (anim instanceof Dog) { Dog dog = (Dog) anim; dog.bark(); } } }
Here, in the teach() method, we check if there is an instance of a Dog object passed in, downcast it to the Dog type and invoke its specific method, bark().
Okay, so far you have got the nuts and bolts of upcasting and downcasting in Java. Remember:
- Casting does not change the actual object type. Only the reference type gets changed.
- Upcasting is always safe and never fails.
- Downcasting can risk throwing a ClassCastException, so the instanceof operator is used to check type before casting.
That’s all for upcasting and downcasting today.
Other Recommended Tutorials:
- 9 Rules about Constructors in Java
- 12 Rules and Examples About Inheritance in Java
- 12 Rules of Overriding in Java You Should Know
- 10 Java Core Best Practices Every Java Programmer Should Know
- Understand Interfaces in Java
- Understand abstraction in Java
- Understand encapsulation in Java
- Understand inheritance in Java
- Understand polymorphism in Java
- Understand variables passing in Java
Comments
Animal anim = dog; //Enough
anim.eat(); // fails if eat() is not overridden. Try!!
two references anim and dog, are there now. reference does not 'change'.
Entire article is absolute trash!
Downcasting được dùng thường xuyên em ạ. Phổ biến trong hàm equals(). Em xem ví dụ ở bài viết này: codejava.net/.../...
Nếu được anh có thể cho em một vài ví dụ cụ thể không?
Thanks anh