class TestGet {   
  
    public void a() {   
        System.out.println("aaa");   
    }   
  
    public void b() {   
        a();   
    }   
}   
class TestGet2 extends TestGet {   
  
    public void a() {   
           
        System.out.println("bbb");   
    }   
  
    public static void main(String[] args) {   
        TestGet t = new TestGet2();   
        t.b();   
    }   
}  
面试官说打印: aaa 
到底是打印bbb还是aaa,求解释

解决方案 »

  1.   

    在new TestGet2()的时候已将父类的  public void a() 重写所以调用的时候会调用自己的 所以执行的是bbb;如果public void a() 改成的是 private,那么重写不了,这时是 aaa
      

  2.   

    但是对t是一个父类对象,它应该调用自己的方法啊
    t.b(); 他调用了父类的b方法,再根据b方法调用父类自己的a方法
      

  3.   

    子类方法对父类同名方法的覆盖将清除父类方法占用的内存,从而使父类方法在子类对象中不复存在。故调用t.b()后,调用的是覆盖后的a方法,也就是TestGet2中的a方法
      

  4.   

    class TestGet2 根本就没有自己的b方法,调用的是父类的b方法
    当然打印出来的是aaa
      

  5.   

    动态方法查找,JAVA基础了。打印的是bbb。 
    t instanceof TestGet2 为true
    简单来讲(但不确切),当对象t在父类中找到a方法后,还会继续在子类中找是否存在方法覆盖。
    如果覆盖,还是会调用子类方法。 打印bbb
      

  6.   

    csdn 的水货程序员真多啊明显的bbb 嘛..诶
      

  7.   

    楼主需要明白 TestGet t = new TestGet2();   
      t.b();    t 永远指向的是TestGet2()实例,不管其定义时是TestGet还是什么类型,当通过这个t调用方法时,方法的行为总是表现出他们实际类型的行为所以,这里最终的  打印出 bbbPS: 文思创新面试官也忒水了吧。
      

  8.   

    如果是静态的方法结果就不一样了! 会调用定义的类的方法class TestGet {    public static void a() {   
    System.out.println("aaa");   
    }    public static void b() {   
    a();   
    }   
    }public class TestGet2 extends TestGet {    public static void a() {    System.out.println("bbb");   
    }    public static void main(String[] args) {   
    TestGet2 t = new TestGet2();   
    t.b();   
    }
      

  9.   

    刚开始以为是aaa,后来经过测试确实是bbb,貌似把两个函数改成构造函数就是aaa了吧
      

  10.   

    为什么改为 static的后就不一样了 。
      

  11.   

    不知道的也不去执行下,答案是bbb如果熟悉jvm实现中常用的方法表,那么就很容易理解了
      

  12.   

    static没有多态的概念,也就是说不存在方法重写,只有方法隐藏的概念,它是根据引用的类型来调用的
      

  13.   

    按面试官的答案来看,他应该是个C++程序员。C++在类的继承上有virtual关键字,而Java是单继承,所以不用virtual.在C++下,这题答案是aaa(当然程序要改成c++的风格)解释一下(希望有用)在调用了b()后,b()调用类A的a(),而a()没有virtual,所以不存在a的虚表和虚指针,所以直接调用A的a(),所以输出aaa.
    假若类A的a()的定义前有virtual,则在调用a()的时候,虚指针会指向虚表,找到子类B的a方法,输出bbb.
      

  14.   

    bbb, 继承 、多态(方法重写、父类引用指向子类对象)
      

  15.   

    to14楼:static方法是不能被子类覆盖的,即使在子类重写了,当子类调用此方法,依然是父类的
      

  16.   

    受教了,终于搞明白static方法是什么意思了
      

  17.   

    实例方法的调用,先在当前实例指向的class对象的方法表中找,找不到则找它的父类,父类的父类,一直递归到Object,再也找不到则抛出no such method异常。不管它是被谁调用,这个问题里,TestGet2的a方法经由父类的b方法调用,但它是在TestGet2实例上调用的。所以一定先在当前实例的class对象的方法表中查找。而不会介意是谁来发起调用的。
      

  18.   

    bbb
    子类重写了父类的member方法
      

  19.   

    是  bbb ,因为TestGet2类已经重写了a方法,所以b方法中调用的是TestGet2类的a方法,测试一下就知道了啊
      

  20.   

    我也想成是aaa了,看来得继续学习
      

  21.   

    我顺便请教下这题的答案又是多少呢?为什么呢?class A {   
      int i=1;   
      public void printI() {   
        System.out.println("i="+i);   
      }   
    }   
      
    public class B  extneds A{   
      int i=2;   
      public static void main(String[] args) {   
        A b=new B();   
        b.printI();   
      }   
    }  
      

  22.   

    如果换成这样(把“A b=new B();”改成“B b=new B();”),运行结果又是多少呢class A {   
      int i=1;   
      public void printI() {   
        System.out.println("i="+i);   
      }   
    }   
      
    public class B  extneds A{   
      int i=2;   
      public static void main(String[] args) {   
        B b=new B();   
        b.printI();   
      }   
    }  
      

  23.   

    以上两个程序,printI()方法都没有被重写,所以都直接调用A类的方法啊,都是1
      

  24.   

    bbb啊,这个面试官其实是在考察你的性格吧?
      

  25.   


    兄台,你说的没错,但为什么会这样呢?你有没有一个比较详细的解释:)在lz的例子里,也是先调用没有被重写的父类方法b(),然后在该方法里调用到一个有被重写的方法a()。
    所以最后选择了子类里的a()来执行而这例子看起来也差不多啊,i在子类里也被重写了,为什么jvm在选择打印i的时候会打印父类的i而不会打印出有被重写子类的i呢?
      

  26.   

    19楼这里根据引用类型来调用的说法明显是错的class TestGet {       public static void a() {   
            System.out.println("aaa");   
        }       public static void b() {   
            a();   
        }   
    }public class TestGet2 extends TestGet {       public static void a() {           System.out.println("bbb");   
        }       public static void main(String[] args) {   
            TestGet2 t1 = new TestGet2();   
            t1.b(); //子类引用类型调用
             TestGet t2 = new TestGet2();  
            t2.b(); //父类引用类型调用
        }
    这段代码无论是父类引用类型还是子类引用类型调用b()方法,输出结果都是:aaa
      

  27.   

    呵呵,在Eclipse写一下就行了呀
      

  28.   

    Dynamic Method Dispatch is the mechanism by which a call to an overridden method is resolved at run time, rather than compile time.
    This is how Java implements run-time polymorphism.
      

  29.   

    [color=#FF0000]楼上水人好多 明显的bbb[/color]
      

  30.   

    楼上水人好多 明显的bbb
      

  31.   

    bbb,这是多态的一种应用,
    当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中被定义过的,也就是说被子类覆盖的方法。