public class CompileTimeMethodBinding
{

	public static class A {}
	public static class B extends A {}
	public static void foo (A a) { System.out.println("A"); }
	public static void foo (B b) { System.out.println("B"); }

	public class E {}
	public class F extends E {}
	public void foo (E e) { System.out.println("E"); }
	public void foo (F f) { System.out.println("F"); }

	public static void trystatic()
	{
		A a = new A();
		A b = new B();
		B c = new B();

		foo(a);
		foo(b);
		foo(c);
	}

	public void trydynamic()
	{
		E e = new E();
		E f = new F();
		F g = new F();

		foo(e);
		foo(f);
		foo(g);
	}

	public static void main (String[] args)
	{
		trystatic();
		new CompileTimeMethodBinding().trydynamic();
	}
}

/* Output: A A B E E F 
 * So, all this binding is done at compile time based on the
 * arguments' references' types, *not* the types of the
 * arguments' values.  */

