What is Upcasting in Java?
Upcasting means converting a subclass object into a superclass reference. It is done automatically and allows access only to the superclass methods and variables.
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
void sound() {
System.out.println("Dog barks");
}
}
public class TestUpcasting {
public static void main(String[] args) {
Animal a = new Dog(); // Upcasting
a.sound(); // Output: Dog barks
}
}
In the above code, the reference variable of parent class (Animal) refers to the object of child class (Dog), which shows polymorphism in action.
Benefits of Upcasting
- Increases flexibility and reusability of code.
- Enables runtime polymorphism.
- Makes code more generic and easier to maintain.
Downcasting in Java
Downcasting converts a superclass reference back to subclass reference. It requires explicit casting and should be done carefully to avoid runtime exceptions.
Animal a = new Dog(); // Upcasting
Dog d = (Dog) a; // Downcasting
d.sound();
Downcasting lets us access subclass-specific methods, but always ensure type safety using the instanceof keyword.
Miscellaneous OOPs Concepts
abstract class Shape {
abstract void draw();
}
class Circle extends Shape {
void draw() {
System.out.println("Drawing Circle");
}
}
class Square extends Shape {
void draw() {
System.out.println("Drawing Square");
}
}
public class TestShapes {
public static void main(String[] args) {
Shape s1 = new Circle(); // Upcasting
Shape s2 = new Square();
s1.draw();
s2.draw();
}
}
This example demonstrates abstraction, inheritance, polymorphism, and upcasting all working together to achieve object-oriented design.
Best Practices
Always ensure type compatibility before downcasting
Use instanceof operator to prevent runtime errors
Maintain a clear and consistent class hierarchy
Use upcasting for flexibility and runtime polymorphism