public class Animal { void talk() { throw new Error("what animal am I?"); } class Cat extends Animal { void talk() { System.out.println("meow"); } } class Cow extends Animal { void talk() { System.out.println("moooh"); } } class Dog extends Animal { void talk() { System.out.println("wuff"); } } /* This is the function that's interesting. * How does the compiler generate the call to a.talk? */ static void letAnimalTalk(Animal a) { a.talk(); } public static void main(String []av) { letAnimalTalk(new Cat()); letAnimalTalk(new Cow()); letAnimalTalk(new Dog()); } }