Polymorphism is a fancy computer science term that refers to Java’s ability to use base-class variables to refer to subclass objects, keep track of which subclass an object belongs to, and use overridden methods of the subclass even though the subclass isn’t known when the program is compiled.

Whew! That’s a mouthful. What it boils down to is that whenever a parameter calls for a particular type, you can use an object created from a subclass of that type instead.

For example, suppose you’re developing an application that can play the venerable game Tic-Tac-Toe, and you create a class named Player that represents one of the players. This class has a public method named move that returns an int to indicate which square of the board the player wants to mark.

To keep things simple, the move method blindly chooses the first empty square on the board as its move. That is, of course, a terrible strategy for winning at Tic-Tac-Toe. Therefore, you decide to create a better version of the class, called BetterPlayer. You implement the BetterPlayer class as a subclass of the Player class but override the move method so that the BetterPlayer class makes more intelligent moves than the Player class.

Suppose that you’ve also written a method named MakeAMove in the main class for the Tic-Tac-Toe application (called it TicTacToe). The MakeAMove method looks something like this:

public void MakeAMove(Player p)
    int i = p.move();
    return i;

You could call the MakeAMove method like this:

    int m = MakeAMove(new Player());

In this case, the MakeAMove method will return the first empty square on the board.

But suppose you call it like this:

    int m = MakeAMove(new BetterPlayer());

In this case, the MakeAMove method will return a better thought-out move because the BetterPlayer class uses a better algorithm to determine the player’s next move.