import java.util.concurrent.ThreadLocalRandom;

 * Illustration of runtime polymorphism.
 * @author Drue Coles
public class PetDemo2 {

    public static void main(String[] args) {
        // Inheritance expresses an is-a relationship. Wherever a superclass
        // reference is required, a subtype reference is valid. In particular,
        // Dog is assignment compatible with Pet. An upcast is implicit.
        Pet myPet = new Dog("Isaak", 12945); 
        if (ThreadLocalRandom.current().nextBoolean()) {
            myPet = new Cat("Muffin"); 
        // The following statement will not compile:
        // myPet.fetchStick();
        // The compiler does not know the runtime type of myPet. It checks the
        // method name against the declared type of the variable.
        // Late binding enables runtime polymorphism. The appropriate version of
        // the method will be invoked depending on the runtime type of myPet.