/* Java class that, together with its child classes and a client program, ** is intended to illustrate two features of the Java (and some other ** object-oriented languages): "dynamic dispatch" and "static typing". */ public class AnimalApp { public static void main(String[] args) { Animal x; // Notice x's data type. x = new Animal(); System.out.println("A (generic) animal says " + x.utterance()); x.speak(3); System.out.println(); x = new Cat(); System.out.println("A cat says " + x.utterance()); // Note that, because x is bound to an instance of the Cat class, // the version of utterance() called in the line above is the one // found in the Cat class (despite the fact that 'x' is declared to // be of type 'Animal'). This feature of Java (and other OO languages) // is called, variously, "dynamic dispatch", "runtime dispatch", or // "runtime polymorphism". x.speak(2); System.out.println(); x = new Pig(); System.out.println("A pig says " + x.utterance()); // Because x is bound to an instance of the Pig class at this time, // the version of utterance() called in the line above will be that // in the Pig class. x.speak(7); System.out.println(); x = new Dog(); System.out.println("A dog says " + x.utterance()); x.speak(5); // x.beg(); // The method call above is rejected by the compiler, because the declared // type of x is Animal, and beg() is not a method in (or inherited by) the // Animal class. This feature of Java (and some other OO languages) is // called "static typing". A compiler of a language that employs // static typing ensures that every method call x.y() is guaranteed to // be such that the "target object" x has a method y(), based upon the // declared type of x (as opposed to the runtime instance type of the // object bouond to x). } }