Last Updated on December 27, 2023 by Ankit Kochar
In Java, casting refers to the conversion of one data type to another. Upcasting and downcasting specifically relate to the casting of objects in the context of class hierarchies, commonly associated with inheritance. Upcasting involves converting a reference of a subclass to a reference of its superclass, while downcasting involves converting a reference of a superclass to a reference of its subclass. Understanding and using these concepts are essential for working with polymorphism and leveraging the full potential of object-oriented programming in Java.
Upcasting is inherently safe, as it involves moving from a more specific type to a more general type. On the other hand, downcasting carries some risk, and developers need to ensure that the object being cast is indeed an instance of the subclass to avoid runtime errors.
Typecasting in Java
The process of converting one data type into another is known as typecasting in java. It is one of the most important concepts of java. As it deals with the conversion of one data type into another data type explicitly or implicitly.
Like the data type, we can also typecast the objects.
You can refer to Typecasting in Java for further knowledge on typecasting.
There are two types of object typecasting available in java and they are mentioned below:
- Upcasting
- Downcasting
Upcasting in Java
In simple words upcasting in java is a type of object typecasting where we are typecasting a child object to a parent object. The upcasting is done implicitly there is no need to explicitly refer to the parent class. The upcasting gives us the benefit of accessing all the methods and variables of the parent class. But in upcasting we cannot access all the variables and methods of the child class. We can only access some specified methods and variables of the child class. Upcasting can also be referred to as Widening and Generalization.
Syntax of Upcasting in Java
The syntax of upcasting in java is given below:
Parent p= new Child();
Example of Upcasting in Java
Below is the example of upcasting.
class Vehicle{ void drive(){ System.out.println("Driving a vehicle..."); } } class Car extends Vehicle{ void drive(){ System.out.println("Driving a car..."); } void speedUp(){ System.out.println("Speeding up a car..."); } } class Main{ public static void main(String[] args){ Vehicle v = new Car(); v.drive(); } }
Output
Driving a car… when a reference variable of a superclass is assigned to a reference variable of
Explanation of the above example
In the above example we have a parent class Vehicle and a child class with the name Car. The Car class extends the Vehicle class and overrides the drive() method. In the main() class we have created an object of the car class and then assign it to the reference variable of the vehicle class.
Even though we have assigned a Car object to a Vehicle reference variable, the drive() method of the Car class is invoked because the Car class overrides the drive() method of the Vehicle class.
Downcasting in Java
Another form of object typecasting is downcasting. A parent class reference object is given to the child class during downcasting. Although it is not possible to give a parent class reference object to a child class in Java, if downcasting is used, there won’t be any compile-time errors. The "ClassCastException" is thrown when we attempt to execute it. The question is, why is downcasting permitted by the compiler if it is not feasible in Java? In some Java situations, downcasting is an option. The master class in this case refers to the subclass object.
Syntax of Downcasting in Java
The syntax of downcasting in java is given below:
Child c= (Child) p;
Example of Downcasting in Java
Below is the example of downsampling in java with code implementation.
class Vehicle{ void drive(){ System.out.println("Driving a vehicle..."); } } class Car extends Vehicle{ void drive(){ System.out.println("Driving a car..."); } void speedUp(){ System.out.println("Speeding up a car..."); } } class Main{ public static void main(String[] args){ Vehicle v = new Car(); Car c = (Car) v; c.drive(); c.speedUp(); } }
Output
Driving a car...
Speeding up a car...
Explanation of the above example
In the above example we have a parent-class vehicle and a child-class car. The car extends to the reference of the parent class and overrides the drive method. It also has a new method known as speedup. We have created an object of type car in the main function then downcast it. In the above program, we upcast a Car object to a Vehicle reference variable and then downcast it back to a Car reference variable. This allows us to call the methods of the Car class.
Why do we use Upcasting and Downcasting in Java?
We do not use upcasting too often in java, We use upcasting in java only when the code needs to deal with only the parent class not much with the child class. Whereas we use downcasting when we need to access all the methods of child classes.
Difference between Upcasting and Downcasting
Here are some of the differences between Upcasting and Downcasting.
Basis | Upcasting | Downcasting |
---|---|---|
Direction | It always goes from subclass to superclass. | It goes from superclass to subclass. |
Safety | It is comparatively safe as it does not require checks on runtime. | We need to perform regular checks on runtime. |
Access | In the child class we can only access the methods of the parent class. | We can access the methods of both child and parent classes. |
Method | We can perform this implicitly or explicitly. | We can perform this only explicitly. |
Conclusion
In conclusion, upcasting and downcasting in Java are integral aspects of object-oriented programming that facilitate the manipulation of objects in class hierarchies. Upcasting allows for the flexibility of treating subclasses as instances of their superclass, enabling polymorphic behavior. Downcasting, while powerful, requires careful validation to avoid runtime exceptions and is typically used when specific methods or attributes of a subclass are needed.
These casting mechanisms contribute to the dynamic and adaptable nature of Java’s object-oriented model, allowing developers to write more generic and reusable code while still taking advantage of the specific features of subclasses.
Frequently Asked Questions Related to Upcasting and Downcasting in Java
Below are some frequently asked questions and answers about upcasting and downcasting in java.
1. When is downcasting necessary in Java?
Downcasting is necessary when you need to access methods or attributes specific to a subclass that are not present in the superclass. It is often required to utilize the full functionality of an object within a class hierarchy.
2. What happens if I attempt to downcast without checking the type using instanceof?
If downcasting is attempted without validating the type using instanceof, it may result in a ClassCastException at runtime. This exception occurs when the object being cast is not an instance of the specified subclass.
3. Can interfaces be upcast and downcast in a similar manner as classes?
Yes, interfaces can also be upcast and downcast in Java. An interface reference can be upcast to a reference of its superinterface, and downcasting is performed similarly with the use of the instanceof operator.
4. Are upcasting and downcasting limited to class hierarchies, or do they apply to interfaces as well?
Both upcasting and downcasting apply not only to class hierarchies but also to interfaces. The principles remain the same, allowing for flexibility and polymorphism in the context of both classes and interfaces.
5. Can downcasting be performed on null references?
Attempting to downcast a null reference will result in a NullPointerException. It is essential to ensure that the object being downcast is not null before attempting the operation to avoid runtime errors.