Exercise

Exercise Make up an example to showcase runtime polymorphism for the following type hierarchy:

Solution

Consider the following implementations for the makeSound method:

public class Animal {
  public void makeSound() {
    System.out.println("Grr...");
  }
}
public class Cat extends Animal {
  @Override
  public void makeSound() {
    System.out.println("Meow");
  }
}
public class Dog extends Animal {
  @Override
  public void makeSound() {
    System.out.println("Woof");
  }
}

If we execute the following code,

Animal[] animals = new Animal[5];
animals[0] = new Animal();
animals[1] = new Cat();
animals[2] = new Dog();
animals[3] = new Dog();
animals[4] = new Cat();

for (Animal a: animals) {
  a.makeSound();
}

It will print

Grr...
Meow
Woof
Woof
Meow

JVM dispatches the implementation of makeSound according to actual type of a at each iteration, at runtime.

By the way, does this "for loop" look strange to you?

for (Animal a: animals) {
  a.makeSound();
}

If yes, please review Oracle's Java Tutorial: The for Statement. The syntax is referred to as the enhanced for statement; it can be used with Collections and arrays to make your loops more compact and easy to read.