OOPS Interview Questions · Question 25

What is upcasting and downcasting, and why can downcasting be unsafe?

Interview preparation resource from Gate Smashers.

Interview-ready answer

Upcasting means treating an object of a subtype as one of its supertypes, such as assigning a Cat object to an Animal reference. It is normally implicit and safe because the object is already an instance of the supertype. Downcasting means converting a supertype reference back to a subtype reference. It requires an explicit cast because the reference may actually point to a different subtype. In Java, an invalid downcast throws ClassCastException at runtime. Downcasting should be used only when the runtime type is known or checked; otherwise, prefer polymorphism or a better-typed design.

Java example showing upcasting, a valid downcast, and an invalid downcastjava
class Animal {
    void speak() {
        System.out.println("Animal");
    }
}

class Cat extends Animal {
    @Override
    void speak() {
        System.out.println("Meow");
    }

    void purr() {
        System.out.println("Purr");
    }
}

class Dog extends Animal {
    @Override
    void speak() {
        System.out.println("Woof");
    }
}

public class CastDemo {
    public static void main(String[] args) {
        Animal a = new Cat();       // Upcast: Cat to Animal
        a.speak();                  // Prints "Meow"

        if (a instanceof Cat) {
            Cat cat = (Cat) a;      // Valid downcast
            cat.purr();
        }

        Animal b = new Dog();
        Cat wrong = (Cat) b;        // Throws ClassCastException at runtime
    }
}
Understand it clearly

Upcasting

Upcasting assigns or passes a subtype object through a superclass or interface reference. For example, a Cat can be used as an Animal because Cat is an Animal.

Upcasting changes the static type of the reference, not the object itself. The runtime object remains a Cat, so overridden instance methods still use the Cat implementation.

  • Safety: It is safe when the subtype relationship is valid, because every subtype object is also an object of its supertypes.
  • Syntax: In Java, it is implicit; no cast syntax is required.

Downcasting

Downcasting converts a reference whose static type is a superclass or interface into a reference to a more specific subtype. It is used when subtype-specific operations are needed.

The cast is explicit because the compiler cannot generally prove that the referenced runtime object has the requested subtype.

  • Example: A reference declared as Animal can be cast to Cat only if the object it refers to is actually a Cat or a subtype of Cat.

Why downcasting can be unsafe

A supertype reference can refer to many different concrete subtypes. Therefore, a cast to one particular subtype may be incorrect even though the types are related at compile time.

In Java, an invalid checked downcast fails at runtime with ClassCastException. In languages with unchecked casts, the consequences of an invalid cast are language- and implementation-dependent.

  • Runtime mismatch: If an Animal reference points to a Dog, casting it to Cat is invalid.
  • Design coupling: Frequent downcasts make code depend on concrete implementations, which reduces the benefits of polymorphism and can make the code more fragile.

Using downcasts safely

When a downcast is genuinely required, verify the runtime type before casting, such as with instanceof in Java. Prefer defining the needed operation on the supertype or interface when all relevant implementations can support it.

Generics and well-designed APIs can also preserve type information and reduce the need for casts.

  • Runtime check: Use instanceof before a Java downcast when the runtime type is uncertain.
  • Preferred design: Use polymorphism so callers invoke behavior through the common supertype rather than inspecting and casting concrete subtypes.
Quick comparison
BasisUpcastingDowncasting
DirectionSubtype reference to supertype referenceSupertype reference to subtype reference
Cast syntax in JavaImplicitExplicit
Runtime safetySafe for a valid subtype-to-supertype relationshipSafe only when the runtime object is an instance of the target subtype
Failure in JavaDoes not fail because of the upcast itselfInvalid casts throw ClassCastException
Typical purposeUse objects through a common superclass or interfaceAccess subtype-specific behavior when the concrete runtime type is known