Earlier we talked about how inheritance describes an is-a relationship. For example, a Dog is an Animal. A Cat is an Animal, and so is a Chicken. What if we want to do something like store a bunch of Animal objects in an array and call methods specific to a subclass? For example, the Dog objects might all have a bark() method, but Chickens don’t.

That’s where polymorphism comes in. Polymorphism is a fancy word for saying that instances of subclasses can also be considered instances of their superclass. In code, that might look like this:

Animal MyDog = new Dog();

Notice that this time, instead of declaring myDog to be of type Dog, we’re declaring it of type Animal.

We can also do this with things like arrays:

Animal[] animals = {
		new Dog(),
		new Cat(),
		new Chicken(),
};

Here, I created an array of Dog, Cat, and Chicken objects. This is possible because all of those classes inherit from Animal, so polymorphism applies.

There’s even a special keyword called instanceof which lets you check if an object is an instance of a class. For example, the following code would print 1 on one line and 2 on the next line.

if (myDog instance of Dog) {
	System.out.println(1);
}

if (myDog instance of Animal) {
	System.out.println(2);
}

If myDog was not an instance of Dog or Animal, there are a couple things that could happen. If the 2 things on either side of the instanceof operator are related in some way (through inheritance or implementing*) the expression will evaluate to false. (It will also evaluate to false if the thing on the left is null.) If the 2 things are completely not related, there will be a compile error.

<aside> ⚠️ A class can implement something called an interface, which is similar to inheritance but not quite. We will talk more about interfaces in Ch. 15.

</aside>

Practice

TestShape