/* * T04n05.java -- Polly wants Polymorphism! * * In this program, classes Parrot and Mouse inherit from the abstract * class Animal, and each supplies the required speak() method. * main() demonstrates that, thanks to Java's dynamic (aka late) binding, * Java can figure out which sort of object is being passed to converse() * and therefore can invoke the appropriate speak() method. * * Worth noting: (a) When main() invokes converse() with an Animal variable, * it's clear that Animal's speak() isn't going to be * invoked, because Animal doesn't implement speak(). * Therefore, Java must be examining the object the * variable references instead of the type of the variable. * (b) We can assign the Animal variable to reference a * Parrot or a Mouse object thanks to inheritance; * either "is a" Animal. * (c) As main() shows, casting the object doesn't confuse * Java, because the referenced object hasn't changed. * (d) If you comment out the [abstract String speak();] line * of Animal, the program won't compile. That's because * Java uses the variable type to determine which * messages are available. It then uses the object * type to decide to which method to send that message. * (e) Combining Java's interface mechanism with polymorphism * gives even more power. See the Topic 5 examples. */ import java.io.*; abstract class Animal { abstract String speak(); // try commenting out this line } class Parrot extends Animal { String speak() { return "Polly wants polymorphism!"; } } class Mouse extends Animal { String speak() { return "Squeak!"; } } public class T04n05 { static void converse (Animal beast) { String answer; answer = beast.speak(); System.out.println(beast.getClass().getName() + " says: '" + answer + "'."); } public static void main (String [] args) { Animal critter; critter = new Parrot(); converse(critter); critter = new Mouse(); converse(critter); Mouse mighty = new Mouse(); critter = mighty; // works fine // critter = (Animal) mighty; // would also work fine // critter = (Parrot) mighty; // won't work at all -- why not? converse(critter); } }