一直以为自己多态学的不错,今天拿到一题目,还是没理解。程序如下:public class Father { public void test(){
System.out.println("Father.test()");
}
public Father(){
System.out.println("Father.Father()");
test();
}
}public class Son extends Father { public Son(){
System.out.println("Son.Son()");
test();
}
public void test(){
System.out.println("Son.test()");
}

public static void main(String[] args) {
Son son = new Son();
}
}我在子类里new了一个Son,而且类型也是Son,并没有用到多态啊,为什么在父类的构造器里的test方法调用的是子类的test方法呢?

解决方案 »

  1.   

    此回复为自动发出,仅用于显示而已,并无任何其他特殊作用
    楼主【milooxu】截止到2008-07-28 21:14:48的历史汇总数据(不包括此帖):
    发帖的总数量:2                        发帖的总分数:20                       每贴平均分数:10                       
    回帖的总数量:3                        得分贴总数量:1                        回帖的得分率:33%                      
    结贴的总数量:2                        结贴的总分数:20                       
    无满意结贴数:1                        无满意结贴分:20                       
    未结的帖子数:0                        未结的总分数:0                        
    结贴的百分比:100.00%               结分的百分比:100.00%                  
    无满意结贴率:50.00 %               无满意结分率:100.00%                  
    敬礼!
      

  2.   

    输出结果应该是:
    Son.Son()
    Son.test()
    不知道对不?请指点。为什么在父类的构造器里的test方法调用的是子类的test方法呢?
    回答:因为父类和子类里面都有一个test方法,子类把父类里的test()覆盖掉了。所以,当我们创建一个子类的对象时,调用的是子类的test()。
      

  3.   

    但是如果我们创建父类的一个对象,那么就会调用父类里面的test方法。
      

  4.   

    输出是: 
    Father.Father()
    Son.test()
    Son.Son()
    Son.test()
      

  5.   

    有本书上记得看过。
    应该是这样的:这是构造方法调用的问题!
    当你调用子类的构造方法时候,要先调用父类的构造方法,然后再调用子类的。
    那第二个为什么输出的是Son.test()呢,因为在子类中覆盖了父类中的方法。如果子类中的test改成test2输出就是Father.test()了。
    应该是这样的把,有点忘记了。
      

  6.   

    本人的处女回帖~~~因为son本身是Father的子类
    当你调用Sun()的构造函数public Son()时,
    相当于是这样的:
    public Son(){ 
    super.Father();
    System.out.println("Son.Son()"); 
    test(); 
    }
    没有爸爸,哪来的孩子啊??对不对
    这样的话
    你的程序等价于先执行了
    System.out.println("Father.Father()"); 
    test(); 
    然后执行了
    System.out.println("Son.Son()"); 
    test(); 所以答案是:
    Father.Father() 
    Son.test() 
    Son.Son() 
    Son.test()
    明白了吗??不明白的话加我QQ 64832013
    大家共同进步~~~
      

  7.   

    Father.Father() 
    Father.test()
    Son.Son() 
    Son.test() 刚开始还以为是这个答案,呵呵
      

  8.   

    这个我还是知道的,我的意思是我为什么在父类的构造器调test方法会调用子类的方法。
    如果我Father f = new Son(); 的话这是多态我理解,但我现在是Son son = new Son(); 这根本就没多态,只是一个继承关系而已。
      

  9.   

    恶补thing in java后得出:这是构造器内部的多态方法问题!
    如果在一个构造器的内部,同时调用在构造的那个对象的某个动态绑定方法,就要用到那个方法的被覆盖后的定义。
    构造器内部有多态方法时怎么调用构造器呢?
    1):在其他任何事情发生之前,将分配给对象的储存空间将初始化成二进制的零。
    2):调用被覆盖的方法。
    3):按照申明的顺序调用成员的初始化。
    4):调用子类的构造器主体。
    举个书上的例子:abstract class Glyph {
      abstract void draw();
      Glyph() {
        System.out.println("Glyph() before draw()");
        draw(); 
        System.out.println("Glyph() after draw()");
      }
    }class RoundGlyph extends Glyph {
      int radius = 1;
      RoundGlyph(int r) {
        radius = r;
        System.out.println(
          "RoundGlyph.RoundGlyph(), radius = "
          + radius);
      }
      void draw() { 
        System.out.println(
          "RoundGlyph.draw(), radius = " + radius);
      }
    }public class PolyConstructors {
      public static void main(String[] args) {
        new RoundGlyph(5);
      }

    输出
    Glyph() before draw();
    RoundGlyph.draw(),radius=0;//radius=0应为步骤1的初始化
    Glyph() after draw();
    RoundGlyph.RoundGlyph() radius=5;
    应该ok了把……
    其实像这种构造一点都不好。
    编写构造器的时候有一条准则:尽可能用简单的方法使对象进入正常状态,如果可以得话,避免调用其他方法。在构造器唯一能能够安全调用的那些方法是基类中的final方法。
      

  10.   

    关于多态,耐心点,找找思路
    其实上
    A xx=new A();你也可以理解成xx是对对象new A()的引用...
      

  11.   

    Father f = new Son(); 即使是这样,执行结果也是一样的.
      

  12.   


    输出结果是: Father.Father()
                Son.test()
                Son.Son()
                Son.test()原因:当你调用Son()构造方法创建son对象时,因为Son是Father的子类,所以要先创建父类对象,
    就像八楼说的,没有爸爸哪来孩子。
    这样的话就要先执行Father()构造方法,所以先输出Father.Father(),
    然后本来是接着执行Father类里面的test()方法的,可是因为子类重写了父类里面的test()方法,相当于覆盖了它,
    所以要执行子类的test()方法,输出Son.test(),
    再下去就是执行子类的构造函数了,再依次输出Son.Son(),Son.test()
      

  13.   


    我还是没有理解为什么父类构造器里面的test()方法实际调用的是子类的test()方法。。
      

  14.   

    顶下.深刻理解多态,还需要好好理解
    static
      

  15.   

    因为在创建子类对象时,要先调用父类的构造函数,而Father.Father()里又调用了Father.test()成员函数时,此时传递的是子类对象的引用,也就是son的引用,类Son中,重写了test()成员函数,所以编译器就会去调用Son.test()
      

  16.   

    如果在子类Son中,不去重写test()方法,则输出结果就是
    Father.Father()
    Father.test() ---------调用的是父类的test()方法
    Son.Son()
    Father.test()---------调用的是父类的test()方法