Upcasting and Downcasting in Java

In this tutorial we are going to understand the concept of upcasting and downcasting in Java with example and learn about their use in the modern programming techniques.

Upcasting in Java

Upcasting basically refers to moving up in the class hierarchy. So what does the last line mean?

We are going to understand this using a simple example where Game is the base class and Cricket and Chess are two of its subclasses.

Game.java

public class Game{

	public void play(){
		System.out.println("Game is being played");
	}

	public void noOfPlayers(){
		System.out.println("No of players depend upon the game");
	}

	public void winner(String name){
		System.out.println("Winner is : " + name);	
	}
}

Cricket.java

public class Cricket extends Game{

	public void noOfPlayers(){
		System.out.println("22");
	}

	public void teams(){
		System.out.println("2");	
	}
}

Chess.java

public class Chess extends Game{

	public void noOfPlayers(){
		System.out.println("2");
	}
}

UpCasting.java

public class UpCasting{

	public static void main(String[] args){
		
		//UpCasting.
		Game game = new Cricket();

		game.play();
		game.noOfPlayers();
		game.winner("A");
	}
}

So in upcasting we actually cast i.e., create an object of Cricket class and assign it to a variable of it’s base class (here Game). In upcasting the overridden methods of the derived class are accessible but newly created methods of the subclass (here, teams() in Cricket) are not accessible.

One more point of upcasting is that, it is always aloud i.e., you can upcast any object to a object of it’s supertype (base class) and this casting is implicit that is compiler automatically upcast any object to it’s base class.

Usage

Upcasting is used when you want to generalise a function or property so that it can be used by any of it’s subtype.

In below example the method startGame() actually calls the play() of the any object passed to. So to generalise this method, we have used upcasting.

GameStart.java

public class GameStart{

	public void startGame(Game game){
		game.play();
	}
}

Main.java

public class Main{
	public static void main(String[] args){
		
		GameStart start = new GameStart();
		Start.startGame(new Cricket());
		Start.startGame(new Chess());
	}
}

Downcasting in Java

Downcasting is the down movement in the class hierarchy. Let’s understand the meaning of this line.

We are going take an example for a better understanding where Game is the base class and Cricket and Chess are two of it’s subclasses.

Game.java

public class Game{

	public void play(){
		System.out.println("Game is being played");
	}

	public void noOfPlayers(){
		System.out.println("No of players depend upon the game");
	}

	public void winner(String name){
		System.out.println("Winner is : " + name);	
	}
}

Cricket.java

public class Cricket extends Game{

	public void noOfPlayers(){
		System.out.println("22");
	}

	public void teams(){
		System.out.println("2");	
	}
}

Chess.java

public class Chess extends Game{

	public void noOfPlayers(){
		System.out.println("2");
	}
}

In Downcasting we cast i.e., explicitly tell the compiler to convert an object of supertype into an object of subtype (derived class). So the main point to remember here is that you should have a prior knowledge of the actually type of the object which is casted into it’s subtype (derived class) and these two must match otherwise casting will fail throwing a ClassCastException. This exception occurs when an object is casted to some other subtype to which it does not belong, as in the error section of the DownCasting file the object of Cricket (game) cannot be casted into Chess.

To avoid this exception and to be sure that the object type matches to the actual type of the object that is being casted, we use Java instanceof operator with an if condition.

Downcasting is always explicit and we need to provide the name of the class in “()”, after the assignment operator “=”, to which we want to cast the object.

DownCasting.java

public class DownCasting{

	public static void main(String[] args){

		//Downcasting
		Game game2 = new Cricket();
		
		//Error
		//Chess chess = (Chess) game2;
		//Solution :

		if(game2 instanceof Cricket){
			Cricket cricket = (Cricket) game2;	
			game2.play();
			game2.noOfPlayers();
			game2.winner("B");	
		}

		else if(game2 instanceof Chess){
			Chess chess = (Chess) game2;
			game2.play();
			game2.noOfPlayers();
			game2.winner("B");			
		}
	}
}

Usage

Downcasting is used when you want to perform some specific operation in a generalised method depending upon the subtype of object.

In the example, we want to call the teams() method of the Cricket class in the generalised method startGame() if the object passed is an instanceof Cricket.

GameStart.java

public class GameStart{

	public void startGame(Game game){
		game.play();
		if(game instanceof Cricket){
			game.teams();
		}
	}
}

Upcasting and Downcasting in Java

Conclusion

  • Upcasting is upward movement in class hierarchy while downcasting is downward movement.
  • Upcasting is implicit and downcasting is explicit and programmer has to provide the class to which the object is to be casted.
  • Upcasting never fails while downcasting may fail if the actual type of the object and casting class do not match.

Comment below if you have queries related to above tutorial for upcasting and downcasting in Java.

1 thought on “Upcasting and Downcasting in Java”

Leave a Comment

Your email address will not be published. Required fields are marked *