输出:
第一步打印,因为创建a1对象,a1对象只是类A的一个普通实例对象,所以a1只能调用类A中的两个方法。a1.show(b),因为没有以类B作为参数的方法,但是B是A的子类,所以执行public String show (A obj),所以输出A and A ;
第二步打印,a1调用方法,同第一步,没有以类C作为参数的方法,但是C是A的子类,所以执行public String show (A obj),输入 A and A ;
第三步打印,a1调用方法,同第一步,此时参数类型为D,类A中存在以D类型为参数的方法,所以调用public String show (D obj),输出 A and D ;
第四步打印,A a2 = new B(); 此语句为父类引用指向子类对象,此时a2只能调用A中的方法或者A的子类重写的A的方法。a2.show(b),类A中没有以类型B作为参数的方法,又因为B是A的子类,所以执行public String show (A obj),在A的子类B中,存在public String show (A obj)方法,所以应该执行重写后的方法,所以输出 B and A ;
第五步打印,a2.show(c);即同第四步,a2只能调用A中的方法或者A的子类重写的A的方法。A中没有以C类型为参数的方法,C也为A的子类,所以执行public String show (A obj),此方法在A的子类B中被重写,所以执行B类的public String show (A obj),即输出 B and A ;
第六步打印,a2.show(d);类A中存在以类型D为参数的方法,直接执行public String show (D obj),输出 A and D ;
第七步打印,b.show(b);B b= new B() 声明类型B的对象b。b可以调用B类中的方法和B的父类A的方法,也需要注意B的子类对B中方法的重写(此题C和D没有任何内容,没有对B的重写)。此时B类中共包含三个方法,分别是以类型D、类型A、类型B作为参数的方法,b.show(b)调用以类型B为参数的方法,所以执行public String show (B obj),输出为B and B ;
第八步打印,b.show(c);与第七步一样,此时参数为C类型,因为没有以类型C为参数的方法,但C直接继承了B,为B的子类,所以执行public String show (B obj),这里注意执行的是类型B中的这个方法,因为继承过后已经对此方法重写,所以输出 B and B ;
最后一步,b.show(d);以类型D作为参数,B类中共包含三个方法,分别是以类型D、类型A、类型B作为参数的方法,这个以类型D作为参数的方法是从B的父类A中继承过来的,所以直接执行public String show (D obj),输出为 A and D ;