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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Crystal静新 中级黑马   /  2014-4-10 18:49  /  774 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

package com;

public class Test {
    public static void main(String[] args) {
        new Child();
    }
}

class Base {
    public int i = 2;

    public Base() {
        this.dispaly();
    }

    public void dispaly() {
        System.out.println("Base");
        System.out.println(i);
    }
}

class Child extends Base {
    public int i = 22;

    public Child() {
        i = 222;
    }

    public void dispaly() {
        System.out.println("Child");
        System.out.println(i);
    }
}
输出结Child 0
i 0

2 个回复

倒序浏览
本帖最后由 赵小豪 于 2014-4-10 19:19 编辑

1.你new了一个子类对象,先走到public Child(){,注意它并没有走下去,而且走到了父类public Base() {};
2.当走到父类public Base() {};则执行了空构造方法中的this.dispaly();;
3.此时的this,代表着引用对象Child,所以运行子类中的    public void dispaly() ;
4.只要创建子类对象,当子类方法跟父类一样时则进行覆盖;
5.所以运行       System.out.println("Child");        System.out.println(i);输 出Child和0
6.为什么会是0,因为你创建子类对象时没有进行初始化;
7.public int i = 22;这句话并没有被执行到,所以i默认值为0.
8.这也是为什么有时我们需要创建带参的构造函数,目的就是为了初始化数据。
9.需要注意的是运行子类是先走父类再走子类,子类会覆盖父类中的同名一样的方法。
回复 使用道具 举报 1 0
本帖最后由 呆呆沙师妹 于 2014-4-11 17:23 编辑

赞同楼上观点!Java语言奉行单继承机制,Child类的直接父类是Base,Base类的直接父类是Object类。
创建实例对象进行初始化时,由子类沿继承关系,向上到达所有类的超类Object类中,若有静态代码块,先则先执行,执行顺序为从Object类到创建实例的子类,之后从Object类往下,依次执行类中的普通代码块、构造函数等等。
由于非静态成员属性随实例加载,在实例未加载前,成员属性值尚未初始化,故i为0。
  1. class Child extends Base {
  2. public int i = 22;

  3. public Child() {
  4. super(); //隐含了super()语句
  5. i = 222;
  6. }
复制代码
这里有一经典实例演示静态代码块、普通代码块、构造函数之间的先后执行顺序,也可从中查看单继承机制下,实例创建的初始化过程。

  1. <P>//静态代码块、普通代码块、构造函数

  2. class ConstructorDemo{

  3.       public static void main( String[] args ) throws Exception
  4.       {
  5.              Leaf lf = new Leaf( "haha" );
  6.              System.out.println();
  7.              Leaf lf2 = new Leaf();
  8.       }</P>
  9. <P>
  10. class Root
  11. {
  12.       static
  13.       {
  14.             System.out.println( "我是Root的静态构造代码块!" );
  15.       }
  16. </P>
  17. <P> </P>
  18. <P>     {
  19.             System.out.println( "我是Root的构造代码块!" );
  20.       }

  21.       Root()
  22.       {
  23.       System.out.println( "我是无参数的Root构造函数!" );
  24.       }
  25. }

  26. class Mid extends Root
  27. {
  28.       static
  29.       {
  30.             System.out.println( "我是Mid的静态构造代码块!" );
  31.       }

  32.       {
  33.             System.out.println( "我是Mid的构造代码块!" );
  34.       }

  35.       Mid()
  36.       {
  37.             System.out.println( "我是无参数的Mid构造函数!" );
  38.       }

  39.       Mid( String s )
  40.       {
  41.             this();
  42.             System.out.println( "我是有参数的Mid构造函数!" );
  43.       }
  44. }

  45. class Leaf extends Mid
  46. {
  47.       static
  48.       {
  49.             System.out.println( "我是Leaf的静态构造代码块!" );
  50.       }

  51.       {
  52.             System.out.println( "我是Leaf的构造代码块!" );
  53.       }

  54.       Leaf()
  55.       {
  56.             System.out.println( "我是无参数的Leaf构造函数!" );
  57.       }

  58.       Leaf( String s )
  59.       {
  60.             this();
  61.             System.out.println( "我是有参数的Leaf构造函数!" );
  62.       }
  63. }</P>
复制代码
上面程序执行结果为:
我是Root的静态构造代码块!
我是Mid的静态构造代码块!
我是Leaf的静态构造代码块!
我是Root的构造代码块!
我是无参数的Root构造函数!
我是Mid的构造代码块!
我是无参数的Mid构造函数!
我是Leaf的构造代码块!
我是无参数的Leaf构造函数!
我是有参数的Leaf构造函数!
我是Root的构造代码块!
我是无参数的Root构造函数!
我是Mid的构造代码块!
我是无参数的Mid构造函数!
我是Leaf的构造代码块!
我是无参数的Leaf构造函数!


回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马