关于java 继承链方法调用问题

public class PolymorphismTest {
     class A {
        public String show(D obj) {
            return ("A and D");
        }

        public String show(A obj) {
            return ("A and A");
        } 

    }

     class B extends A{
        public String show(B obj){
            return ("B and B");
        }

        public String show(A obj){
            return ("B and A");
        } 
    }

     class C extends B{

    }

     class D extends B{

    }


        public static void main(String[] args) {
            A a1 = new PolymorphismTest().new A();
            A a2 = new PolymorphismTest().new B();
            B b = new PolymorphismTest().new B();
            C c = new PolymorphismTest().new C();
            D d = new PolymorphismTest().new D();

            System.out.println("1--" + a1.show(b));
            System.out.println("2--" + a1.show(c));
            System.out.println("3--" + a1.show(d));
            System.out.println("4--" + a2.show(b));
            System.out.println("5--" + a2.show(c));
            System.out.println("6--" + a2.show(d));
            System.out.println("7--" + b.show(b));
            System.out.println("8--" + b.show(c));
            System.out.println("9--" + b.show(d));     
            System.out.println("10--" + a2.show(a1));
        }

}

最后输出
1--A and A
2--A and A
3--A and D
4--B and A
5--B and A
6--A and D
7--B and B
8--B and B
9--A and D
10--B and A

想问下第4与第5条结果为啥不是B and B

玩多态把自己玩蒙了

public class PolymorphismTest {
 class A {
    public String show(D obj) {
        return ("A and D");
    }

    public String show(A obj) {
        return ("A and A");
    } 

  }

 class B extends A{
    public String show(B obj){
        return ("B and B");
    }

    public String show(A obj){
        return ("B and A");
    } 
  }

  class C extends B{
  }

  class D extends B{
  }

  public static void main(String[] args) {

    A a2 = new PolymorphismTest().new B();
    B b = new PolymorphismTest().new B();
    C c = new PolymorphismTest().new C();

    System.out.println("4--" + a2.show(b));
    System.out.println("5--" + a2.show(c));

  }

}

对于A中有如下两个方法

  public String show(D obj);
  public String show(A obj);

对于B中有如下两个方法

  public String show(B obj);
  public String show(A obj);

那你这里a2编译时是A,运行时是B。

A a2 = new PolymorphismTest().new B();

那么对于B中的两个方法,将覆盖A中的就只有

  public String show(A obj);

另外一个通过A的实例根本调用不到

  public String show(B obj);

也就是运行时A中的两个方法是

  public String show(D obj); // A的
  public String show(A obj); // B覆盖A的

当你调用下面的两个方法

  System.out.println("4--" + a2.show(b));
  System.out.println("5--" + a2.show(c));

那当然就是调用到

  public String show(A obj); // B覆盖A的

这就等于你

  Object obj = new Object();
  Object a = new A(); // A里面有show()方法
  // a.show(); // 根本调不到

因为A提供了show(A obj)方法,而a2 是A类型的new出个子类B,自然调用子类的覆盖的方法B中的show(A obj)

A a2 = new PolymorphismTest().new B();
System.out.println("4--" + a2.show(b));
这里有个陷阱,以为右边是一个new B(),所以就直接在B类中找方法,又因为参数是B,所以就以为是调用show(B obj)
而实际上程序运行的步骤是这样的:
1. 首先检查a2的静态类型是A类型,就在A类中找对应的方法,因为A中没有show(B obj), 但是B继承自A,所以找到了show(A obj).
2. 然后在根据a2的实际类型是B,再从B类中找到show(A obj)的重写方法
所以应该是调用B的show(A obj)

如果你对第一点存在质疑,可以将A中的show(A obj)方法改成show(C obj),编译器直接就报错。没有找到适用的方法,说明是由A类型开始检查。