A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 黄树人 于 2012-8-8 22:54 编辑

class Dog
{
        Dog()
        {
                System.out.println("before Dog run");
                run();
                System.out.println("after Dog run");
        }

        public void run()
        {
                System.out.println("Dog run");
        }

}

class SmallDog extends Dog
{
        private int speed = 1;

        public SmallDog(int speed)
        {
                this.speed = speed;
        }

        public void run()
        {
                System.out.println("SmallDog run speed="+speed);
        }
}

class Zoo
{
        public static void main(String[] args)
        {
                new SmallDog(5);


这好像是个5K的面试题,函数中的输出中speed的值是多少,值的调用和初始化具体的步骤是什么,求高手详解

4 个回复

倒序浏览
代码修改如下,红色为增加代码:
  1. class Dog
  2. {
  3.          Dog()
  4.          {
  5.                  System.out.println("before Dog run");
  6.                  run();
  7.                  System.out.println("after Dog run");
  8.          }

  9.         public void run()
  10.          {
  11.                  [color=Red]System.out.println("父类的run()方法");[/color]
  12.                  System.out.println("Dog run");
  13.          }

  14. }

  15. class SmallDog extends Dog
  16. {
  17.         private int speed = 1;

  18.        [color=Red]public SmallDog()
  19.        {
  20.         //super();
  21.        }[/color]

  22.         public SmallDog(int speed)
  23.          {
  24.         [color=Red]System.out.println("子类的有参构造方法");[/color]
  25.                  this.speed = speed;
  26.          }

  27.         public void run()
  28.          {
  29.         [color=Red]System.out.println("子类的run()方法");[/color]
  30.                  System.out.println("SmallDog run speed="+speed);
  31.          }

  32. }

  33. class Zoo
  34. {
  35.          public static void main(String[] args)
  36.          {
  37.                  new SmallDog(5);                 
  38.          }
  39. }
复制代码
说明:
无论是子类的无参还是有参构造方法都默认先调用父类的无参构造方法,只有这样子类实例才能调用父类中的属性和方法。因此,在使用new SmallDog(5)对子类进行实例化的时候,先用调用父类Dog类的无参构造方法,所以会依次先输出"before Dog run",再调用run()方法,再输出"after Dog run",而由于子类SmallDog覆写了父类Dog的run()方法,所以必然调用子类SmallDog的run()方法,而此时子类SmallDog中的speed属性还未赋值(因为还没有调用子类的构造方法),所以输出speed默认值为0,最后,才调用SmallDog的有参构造方法。
回复 使用道具 举报
class Dog
{
             Dog()//步骤4.执行此构造方法
     {   
                           System.out.println("before Dog run");//步骤5输出before Dog run
            run();//步骤6.调用Dog类的 run方法,将会输出Dog run
            System.out.println("after Dog run");//步骤7.输出after Dog run
     }

     public void run()
            {
                         System.out.println("Dog run");
             }

}

class SmallDog extends Dog
{
                 private int speed = 1;

                public SmallDog(int speed)//步骤2.执行此构造方法
         {
                               // super();此处省略了。步骤3.执行Dog类的构造方法,因为Dog类的构造方法也是空参数的。
                              this.speed = speed;//步骤8.将5赋值给 speed
                }

               public void run()
        {
                           System.out.println("SmallDog run speed="+speed);
               }
}

class Zoo
{
                 public static void main(String[] args)
                 {
                                new SmallDog(5);//步骤1.将5传给SmallDog类的构造方法。
          }
}
所以最后speed的值为5,程序会输出:before Dog run
                                                       Dog run
                                                       after Dog run
大家觉得是这样的么,我懂的不多,不对的地方请大家多指点。

回复 使用道具 举报
class Dog
{
        Dog()
        {
                System.out.println("before Dog run");
                run();  /*第三步:访问父类构造函数,当访问到该方法时,因为子类已经将run()方法覆写了,
                                                  所以会运行子类的run()方法,而此时还没有给Speed赋值,所以speed的值应该是0;
                                                */
                System.out.println("after Dog run");
        }

        public void run()
        {
                System.out.println("Dog run");
        }

}

class SmallDog extends Dog//第二步:因为类SmallDog继承了父类Dog,所以子类在访问自己的构造函数之前会先调用父类的构造函数。
{
        private int speed = 1;

        public SmallDog(int speed)
        {
               //其实在这里省略了super();
                                this.speed = speed;
        }

        public void run()
        {
                System.out.println("SmallDog run speed="+speed);
        }
}

class Zoo
{
        public static void main(String[] args)
        {
                new SmallDog(5);//第一步:在内存中开辟空间创建SmallDog的对象,调用该对象的构造函数。
                }
}

所以最后的结果应该是先输出"before Dog run",
在输出子类run()方法的"SmallDog run speed="+speed,而speed=0;
最后输出"after Dog run"。最后结果如下:
before Dog run
SmallDog run speed=0
after Dog run
若是把主函数的new SmallDog(5);改为new SmallDog(5).run();
则结果是
before Dog run
SmallDog run speed=0
after Dog run
SmallDog run speed=5
因为此时已经把5赋值给了speed重新调用了run()方法。
楼上的应该是run()方法调用那里弄错了。
回复 使用道具 举报
已解决,谢谢大家的帮助
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马