Introduction
Casting is converting one data type to another. In inheritance, it’s converting between parent and child class references.
Types of Casting
- Upcasting (Implicit)
- Downcasting (Explicit)
Upcasting
Child to parent conversion (automatic).
Syntax:
Parent p = new Child(); // Implicit upcasting
Example:
class Animal {
void eat() {
System.out.println("Eating");
}
}
class Dog extends Animal {
void bark() {
System.out.println("Barking");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
// Upcasting (implicit)
Animal animal = dog;
animal.eat(); // ✓ OK
// animal.bark(); // ✗ Error: Animal reference can't access Dog methods
}
}
Downcasting
Parent to child conversion (explicit cast required).
Syntax:
Child c = (Child) parentReference;
Example:
class Animal {
void eat() {
System.out.println("Eating");
}
}
class Dog extends Animal {
void bark() {
System.out.println("Barking");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Dog(); // Upcasting
// Downcasting (explicit)
Dog dog = (Dog) animal;
dog.eat(); // ✓ OK
dog.bark(); // ✓ OK now
}
}
Why Casting?
class Shape {
void draw() {
System.out.println("Drawing shape");
}
}
class Circle extends Shape {
double radius;
void draw() {
System.out.println("Drawing circle");
}
double area() {
return Math.PI * radius * radius;
}
}
public class Main {
public static void main(String[] args) {
Shape shape = new Circle(); // Upcasting
shape.draw(); // Works (polymorphism)
// shape.area(); // ✗ Error: Shape doesn't have area()
// Need downcasting to access Circle-specific methods
Circle circle = (Circle) shape;
System.out.println("Area: " + circle.area()); // ✓ OK
}
}
ClassCastException
Runtime error when invalid cast.
class Animal { }
class Dog extends Animal { }
class Cat extends Animal { }
public class Main {
public static void main(String[] args) {
Animal animal = new Cat(); // Cat object
// Dog dog = (Dog) animal; // ✗ Runtime Error: ClassCastException
// Cannot cast Cat to Dog
}
}
instanceof Operator
Check type before casting to avoid errors.
Syntax:
if (object instanceof ClassName) {
// Safe to cast
}
Example:
class Animal { }
class Dog extends Animal {
void bark() {
System.out.println("Bark");
}
}
class Cat extends Animal {
void meow() {
System.out.println("Meow");
}
}
public class Main {
public static void main(String[] args) {
Animal[] animals = {new Dog(), new Cat(), new Dog()};
for (Animal animal : animals) {
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark();
} else if (animal instanceof Cat) {
Cat cat = (Cat) animal;
cat.meow();
}
}
}
}
Complete Example
class Employee {
String name;
double salary;
Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
void work() {
System.out.println(name + " is working");
}
}
class Manager extends Employee {
String department;
Manager(String name, double salary, String department) {
super(name, salary);
this.department = department;
}
void manage() {
System.out.println(name + " manages " + department);
}
}
class Developer extends Employee {
String language;
Developer(String name, double salary, String language) {
super(name, salary);
this.language = language;
}
void code() {
System.out.println(name + " codes in " + language);
}
}
public class Main {
public static void main(String[] args) {
Employee[] employees = new Employee[3];
employees[0] = new Employee("John", 30000);
employees[1] = new Manager("Alice", 50000, "IT");
employees[2] = new Developer("Bob", 40000, "Java");
for (Employee emp : employees) {
emp.work(); // Polymorphic call
// Type-specific operations
if (emp instanceof Manager) {
Manager mgr = (Manager) emp; // Downcast
mgr.manage();
} else if (emp instanceof Developer) {
Developer dev = (Developer) emp; // Downcast
dev.code();
}
System.out.println();
}
}
}
Casting Rules
Valid Casts:
class A { }
class B extends A { }
class C extends B { }
// Upcasting (always safe)
A a = new B(); // ✓
A a = new C(); // ✓
B b = new C(); // ✓
// Downcasting (needs check)
A a = new C();
if (a instanceof C) {
C c = (C) a; // ✓ Safe
}
Invalid Casts:
class Dog { }
class Cat { }
// Dog dog = (Dog) new Cat(); // ✗ No relationship
Primitive Type Casting
Widening (Implicit):
int i = 10;
double d = i; // Automatic
System.out.println(d); // 10.0
Narrowing (Explicit):
double d = 10.5;
int i = (int) d; // Explicit cast needed
System.out.println(i); // 10 (loses decimal)
Casting with Methods
class Animal {
void sound() {
System.out.println("Animal sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Bark");
}
void fetch() {
System.out.println("Fetching");
}
}
class AnimalHandler {
static void handleAnimal(Animal animal) {
animal.sound(); // Polymorphic
// Access Dog-specific method
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.fetch();
}
}
}
public class Main {
public static void main(String[] args) {
AnimalHandler.handleAnimal(new Dog());
}
}
Multiple Levels
class A { }
class B extends A { }
class C extends B { }
public class Main {
public static void main(String[] args) {
A a = new C(); // Upcasting C -> A
// Downcast to B
if (a instanceof B) {
B b = (B) a;
System.out.println("Cast to B successful");
}
// Downcast to C
if (a instanceof C) {
C c = (C) a;
System.out.println("Cast to C successful");
}
}
}
Safe Casting Pattern
public class SafeCasting {
static void processShape(Object obj) {
if (obj instanceof Circle) {
Circle circle = (Circle) obj;
System.out.println("Circle area: " + circle.area());
} else if (obj instanceof Rectangle) {
Rectangle rect = (Rectangle) obj;
System.out.println("Rectangle area: " + rect.area());
} else {
System.out.println("Unknown shape");
}
}
}
Common Mistakes
Mistake 1: Casting Unrelated Classes
class Dog { }
class Cat { }
// Dog dog = (Dog) new Cat(); // ✗ Compile error
Mistake 2: Not Checking Before Downcast
Animal animal = new Cat();
// Dog dog = (Dog) animal; // ✗ Runtime error
// ✓ Correct
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
}
Mistake 3: Unnecessary Casting
Dog dog = new Dog();
Animal animal = dog; // ✓ No cast needed (upcasting)
Dog d = (Dog) animal; // Cast needed (downcasting)
Real-World Example: Collections
import java.util.ArrayList;
class Vehicle { }
class Car extends Vehicle {
void drive() {
System.out.println("Driving car");
}
}
class Bike extends Vehicle {
void ride() {
System.out.println("Riding bike");
}
}
public class Main {
public static void main(String[] args) {
ArrayList<Vehicle> vehicles = new ArrayList<>();
vehicles.add(new Car()); // Upcasting
vehicles.add(new Bike()); // Upcasting
for (Vehicle v : vehicles) {
if (v instanceof Car) {
Car car = (Car) v; // Downcasting
car.drive();
} else if (v instanceof Bike) {
Bike bike = (Bike) v; // Downcasting
bike.ride();
}
}
}
}
Comparison Table
| Feature | Upcasting | Downcasting |
|---|---|---|
| Direction | Child → Parent | Parent → Child |
| Syntax | Implicit | Explicit cast |
| Safety | Always safe | May fail |
| Check needed | No | Yes (instanceof) |
| Example | Parent p = new Child() | Child c = (Child) p |
| Error | Never | ClassCastException |
Pattern Matching (Java 16+)
// Modern Java (16+)
if (animal instanceof Dog dog) {
// dog variable automatically created
dog.bark();
}
// Old way
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark();
}
Quick Reference
// Upcasting (implicit)
Parent p = new Child();
// Downcasting (explicit)
Child c = (Child) p;
// Safe downcasting
if (p instanceof Child) {
Child c = (Child) p;
// Use c
}
// Check multiple types
if (obj instanceof Dog) {
((Dog) obj).bark();
} else if (obj instanceof Cat) {
((Cat) obj).meow();
}
Exam Tips
Remember:
- Upcasting = child to parent (automatic)
- Downcasting = parent to child (explicit)
- Use instanceof before downcasting
- ClassCastException at runtime if invalid
- Upcasting always safe
- Downcasting may fail
- Need (ChildType) for downcast
- Check type in inheritance hierarchy
- No casting between unrelated classes
- Enables polymorphism
Common Questions:
- What is casting?
- Upcasting vs downcasting?
- When to use instanceof?
- What is ClassCastException?
- Why casting needed?
- How to safely downcast?
- Can we cast unrelated classes?
- Implicit vs explicit casting?