/**
 * Overloading y override mezclados. El overloading se decide al compilar,
 * con los tipos estáticos de los argumentos; el override, al ejecutar,
 * con la clase del objeto que recibe el mensaje.
 */
public class TraceDemo {

    public static void main(String[] args) {
        Greeter g = new LoudGreeter();
        String s = "hola";
        Object x = s;                   // el mismo String, visto como Object

        IO.println("1. " + g.greet(s));
        IO.println("2. " + g.greet(x));
        IO.println("3. " + g.greet((String) x));

        Greeter plain = new Greeter();
        IO.println("4. " + plain.greet(x));
    }
}
