☰
Up-casting is casting to a supertype, while downcasting is casting to a subtype. Upcasting and downcasting gives us advantages, like Polymorphism or grouping of different objects. We can treat an object of a child class type to be as an object of its parent class type. This is called upcasting.
Now, anytime an object of parent class type is type cast into a child class type, it is called a downcast.
So why is this called up-casting and down-casting? It is because of the way that inheritance diagrams are normally drawn parent classes are at the top and child classes are down below the parent classes. From Dog, we are moving up the object hierarchy to the type Animal, so we are casting our object "upwards" to its parent type. So it is called up-casting and down-casting is reverse of it.
Lets look at below code for clear understanding:
public class Animal {
public void walk()
{
System.out.println("Walking Animal");
}
}
class Dog extends Animal {
public void walk()
{
System.out.println("Walking Dog");
}
public void sleep()
{
System.out.println("Sleeping Dog");
}
}
class Demo {
public static void main (String [] args) {
Animal a = new Animal();
Dog d = new Dog();
a.walk();
d.walk();
d.sleep();
//upcasting
Animal a2 = (Animal)d;
a2.walk();
//a2.sleep(); error
//downcasting
Animal a3 = new Dog();
//Dog d2 = a3; //compile time error
Dog d2 = (Dog)a3;
d2.walk();
d2.sleep();
//Run time error: Animal cannot be cast to Dog
Animal a4 = new Animal();
//Dog d3 = (Dog)a4;
//d3.walk();
//d3.sleep();
}
}
Output:
Walking Animal
Walking Dog
Sleeping Dog
Walking Dog
Walking Dog
Sleeping Dog
First, you must understand, that by casting you are not actually changing the object itself, you are just labeling it differently. For example, if you create a Dog and upcast it to Animal, then the object doesn't stop from being a Dog. It's still a Dog, but it's just treated as any other Animal and it's Dog properties are hidden until it's downcasted to a Dog again.
Upcasting/Supercasting is always allowed, but downcasting/subcasting involves a type check and can throw a ClassCastException.
In our case, a cast from from Dog to an Animal is a upcast, because a Dog is-a Animal. In general, you can upcast whenever there is an is-a relationship between two classes.
Up-casting is implicit and is safe. What do we mean by safe? Well, we can happily cast Dog to Animal and expect all the properties and methods of Animal to be available.
In down-casting what you're doing is telling the program that you know what the runtime type of the object really is. The program will do the conversion, but will still do a sanity check to make sure that it's possible. In this case, the cast is possible because at runtime animal is actually a Dog.
Down-casting is potentially unsafe, because you could attempt to use a method that the child class does not actually implement. With this in mind, down-casting is always explicit, that is, we are always specifying the type we are down-casting to.
Suppose there is no type cast like below:
Animal animal = new Animal();
Dog dog = animal;
Then this code would give a compile time error instead of a runtime error, because there is no way that an object of the Parent class can ever be downcast to an object of it's child class.
However, if you were to do this:
Animal animal = new Animal();
Dog dog = (Dog) animal;
There won't be any compile time error but You'd get a ClassCastException in runtime. The reason is because animal's runtime type is Animal, and so when you tell the runtime to perform the cast it sees that animal isn't really a Dog and so throws a ClassCastException.
Now, if you do like this:
Animal animal = new Dog();
Dog dog = animal;
Again you will get a compile time error saying "Type mismatch: cannot convert from Animal to Dog" and suggest us to cast.
So to do successfull downcasting we have to code like this:
Animal animal = new Dog();
Dog dog = (Dog) animal;
Idea behind casting, is that, which object is which. You should ask, is Dog an Animal? Yes, it is - that means, it can be cast.
Is Animal a Dog? No it isn't - it cannot be cast.
Is Cat a Dog? No, it cannot be cast.
If you upcast an object, it will lose all it's properties, which were inherited from below it's current position. For example, if you cast a Dog to an Animal, it will lose properties inherited from Dog. Note, that data will not be lost, you just can't use it, until you downcast the object to the right level.
Why is it like that? If you have a group of Animals, then you can't be sure which ones can meow() and which ones can bark(). That is why you can't make Animal do things, that are only specific for Dogs or Cats.
To call a parent class's method you can do super.method() or perform the upcast.
To call a child class's method you have to do a downcast and risk the ClassCastException.
To check if down-casting is valid you can write like this:
if (a.getClass( ) == d.getClass())
{
valid;
}else {
not valid;
}
Note: Upcasting and downcasting are NOT like casting primitives
Sincere thanks from CoreJavaGuru to the author for submitting the above article.