In Java, upcasting and downcasting refer to type conversions between objects that are part of an inheritance hierarchy.
Upcasting:
Upcasting occurs when you convert a subclass type to a superclass type. This is safe and doesn’t require explicit casting because it’s always possible to treat a subclass object as an object of its superclass. It is often referred to as a “widening” conversion.
Example:
class Animal {
void makeSound() {
System.out.println("Some sound");
}
}
class Dog extends Animal {
void makeSound() {
System.out.println("Bark");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
Animal animal = dog; // Upcasting: Dog -> Animal
animal.makeSound(); // Will print "Bark"
}
}
Here, dog
(of type Dog
) is upcast to animal
(of type Animal
). You can call the makeSound
method on animal
, and because of polymorphism, it still calls the overridden method in the Dog
class.
Downcasting:
Downcasting occurs when you convert a superclass type to a subclass type. This is a narrower conversion and can be unsafe. It may cause a ClassCastException
if the object being cast is not actually an instance of the subclass.
Example:
class Animal {
void makeSound() {
System.out.println("Some sound");
}
}
class Dog extends Animal {
void makeSound() {
System.out.println("Bark");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Dog(); // Upcasting: Dog -> Animal
Dog dog = (Dog) animal; // Downcasting: Animal -> Dog
dog.makeSound(); // Will print "Bark"
}
}
In this example, animal
is of type Animal
, but it points to a Dog
object. When you downcast it to Dog
, you need to explicitly cast it (Dog)
. If you tried to downcast an object that isn’t actually a Dog
, like an Animal
that is actually an Animal
object, you would get a ClassCastException
.
Important Note on Downcasting:
Before downcasting, it is a good practice to use instanceof
to check if the object can be safely cast:
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.makeSound();
} else {
System.out.println("This animal is not a dog.");
}
Key Differences:
- Upcasting is always safe and does not require explicit casting. It’s converting a more specific type (subclass) to a more general type (superclass).
- Downcasting is potentially unsafe and requires explicit casting. It’s converting a general type (superclass) to a more specific type (subclass), which may result in a
ClassCastException
if done improperly.