Upcasting and Downcasting
Part of the Object Oriented Programming section of Coddy's Java journey — lesson 30 of 87.
In the previous lesson, you saw how a parent-type variable can hold a child object: Animal myPet = new Dog(). This assignment is called upcasting, and it happens automatically because a Dog is always an Animal.
Upcasting moves up the inheritance hierarchy. It's implicit and always safe:
Dog dog = new Dog();
Animal animal = dog; // Upcasting - automaticWhen you upcast, you can only access methods defined in the parent class. The child-specific methods become hidden, even though the object is still a Dog underneath.
Downcasting goes the opposite direction, converting a parent reference back to a child type. This requires an explicit cast because it's not always safe:
Animal animal = new Dog(); // Upcasting
Dog dog = (Dog) animal; // Downcasting - explicit cast required
dog.bark(); // Now we can access Dog methodsDowncasting is risky. If the object isn't actually the type you're casting to, Java throws a ClassCastException at runtime:
Animal animal = new Cat();
Dog dog = (Dog) animal; // Compiles, but crashes at runtime!The compiler can't catch this error because it only sees the declared types. The actual object type is only known when the program runs. In the next lesson, you'll learn how to safely check an object's type before downcasting.
Challenge
EasyLet's build a media player system that demonstrates both upcasting and downcasting in action. You'll create a hierarchy of media types and practice converting between parent and child references.
You'll organize your code across four files:
Media.java: Create the base class that all media types share. Every media item has atitlefield (String). Include a constructor to initialize it, a getter methodgetTitle(), and a methodplay()that prints:Playing: [title]Song.java: Create a class that extends Media. Songs have an additionalartistfield (String). Usesuperfor the parent initialization. Overrideplay()to print:Playing song: [title] by [artist]. Add a methodshowArtist()that prints:Artist: [artist]Podcast.java: Create another class that extends Media. Podcasts have anepisodefield (int). Overrideplay()to print:Playing podcast: [title] - Episode [episode]. Add a methodshowEpisode()that prints:Episode: [episode]Main.java: Demonstrate upcasting and downcasting with your media types. You'll receive four inputs: a song title, an artist name, a podcast title, and an episode number.First, create a Song and upcast it to a Media reference. Call
play()on this reference to see run-time polymorphism at work.Next, downcast that Media reference back to a Song and call
showArtist()to access the child-specific method.Then, create a Podcast and upcast it to a Media reference. Call
play()on this reference.Finally, downcast that Media reference back to a Podcast and call
showEpisode().
You will receive four inputs: the song title (String), artist name (String), podcast title (String), and episode number (int).
Your output should show four lines - two for the song (its play output and artist info) and two for the podcast (its play output and episode info). Notice how upcasting lets you treat different media types uniformly, while downcasting lets you access their unique features!
Cheat sheet
In Java, upcasting moves up the inheritance hierarchy and happens automatically. A child object can be assigned to a parent-type variable:
Dog dog = new Dog();
Animal animal = dog; // Upcasting - automaticWhen you upcast, you can only access methods defined in the parent class, even though the object is still the child type underneath.
Downcasting converts a parent reference back to a child type. It requires an explicit cast:
Animal animal = new Dog(); // Upcasting
Dog dog = (Dog) animal; // Downcasting - explicit cast required
dog.bark(); // Now we can access Dog methodsDowncasting is risky. If the object isn't actually the type you're casting to, Java throws a ClassCastException at runtime:
Animal animal = new Cat();
Dog dog = (Dog) animal; // Compiles, but crashes at runtime!The compiler can't catch this error because it only sees the declared types. The actual object type is only known when the program runs.
Try it yourself
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Read inputs
String songTitle = scanner.nextLine();
String artistName = scanner.nextLine();
String podcastTitle = scanner.nextLine();
int episodeNumber = scanner.nextInt();
// TODO: Create a Song and upcast it to a Media reference
// TODO: Call play() on the Media reference (demonstrates polymorphism)
// TODO: Downcast the Media reference back to Song
// TODO: Call showArtist() on the Song reference
// TODO: Create a Podcast and upcast it to a Media reference
// TODO: Call play() on the Media reference
// TODO: Downcast the Media reference back to Podcast
// TODO: Call showEpisode() on the Podcast reference
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe this KeywordMethodsFields (Attributes)Constructor MethodConstructor OverloadingRecap - Simple Calculator4Inheritance
Basic Inheritance (extends)The super KeywordMethod Overriding (@Override)Constructor ChainingThe Object ClassSingle & Multilevel InheritWhy No Multi Class InheritRecap - Employee Hierarchy7Special Methods & Object Class
toString() Methodequals() and hashCode()clone() MethodcompareTo() and ComparableComparator InterfaceRecap - Custom Sorting2Access Modifiers & Encapsulate
Access Levels OverviewGetter and Setter MethodsInformation HidingThe final KeywordRecap - Bank Account Manager5Polymorphism
Method Overloading BasicsMethod Overriding (Run-Time)Upcasting and DowncastingThe instanceof OperatorAbstract Classes and MethodsRecap - Shape Calculator8Advanced OOP Concepts
Composition vs InheritanceAggregation vs CompositionInner Nested & Anonymous ClassEnums and Enum MethodsRecords (Java 16+)Sealed Classes (Java 17+)3Class Props & Static Member
Instance vs Static VariablesStatic MethodsStatic BlocksConstants (static final)Recap - Counter & Utility6Interfaces & Abstract Classes
Introduction to InterfacesImplementing InterfacesMulti Interface ImplemenDefault & Static in InterfaceAbstract Classes vs InterfacesFunctional InterfacesRecap - Payment System