黑马程序员技术交流社区
标题:
构造函数的继承问题
[打印本页]
作者:
聖手`书生
时间:
2013-4-4 10:15
标题:
构造函数的继承问题
代码中的执行结果有些迷惑,执行结果如截图,主函数并没有调用Zi(),为什么会执行了它,然后因为父类的构造函数有两个,为什么默认执行了Fu(),不是说默认在子类构造函数第一行执行的是父类空参数的构造函数吗。这两个问题不解,结果也出乎意料。
class Fu //extends Object
{
int num ;
Fu()
{
//super();
num= 60;
System.out.println("fu run");
}
Fu(int x)
{
System.out.println("fu ...."+x);
}
}
class Zi extends Fu
{
Zi()
{
//super();
//super(4);
System.out.println("zi run");
}
Zi(int x)
{
this();
//super();
//super(3);
System.out.println("zi..."+x);
}
}
class ExtendsDemo4
{
public static void main(String[] args)
{
Zi z = new Zi(0);
System.out.println(z.num);
}
}
复制代码
99999.jpg
(9.14 KB, 下载次数: 49)
下载附件
2013-4-4 10:11 上传
作者:
栗俊植
时间:
2013-4-4 10:47
class Fu //extends Object
{
int num ;
Fu() //因为这里有无参构造函数 所以执行它 打印结果为 fu run 第二步
{
//super();
num= 60;
System.out.println("fu run");
}
Fu(int x)
{
System.out.println("fu ...."+x);
}
}
class Zi extends Fu
{
Zi()
{
//super(); 这里你也注释了,默认在子类构造函数第一行有个调用父类无参构造函数: 第一步
//super(4);
System.out.println("zi run");
}
Zi(int x) // 被调用 打印结果为 Zi...0 第四步
{
this();
//super();
//super(3);
System.out.println("zi..."+x);
}
}
class ExtendsDemo4
{
public static void main(String[] args)
{
Zi z = new Zi(0); //new Zi(0) 创建了有参数的子类对象,进行初始化,调用子类有参构造函数 第三步
System.out.println(z.num);
}
}
复制代码
/*
* 对象的初始化顺序:首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,
* 当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,
* 父类的非静态代码块执行完毕,接着执行父类的构造方法;
* 父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。
* 子类的非静态代码块执行完毕再去执行子类的构造方法。
* 总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。
注意:子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过。
*/
作者:
田光峰
时间:
2013-4-4 13:14
class Fu //extends Object
{
int num ;
Fu()
{
//super();
num= 60;
System.out.println("fu run");
}
Fu(int x)
{
System.out.println("fu ...."+x);
}
}
class Zi extends Fu
{
Zi()
{
//super();
//super(4);
System.out.println("zi run");
}
Zi(int x)
{
this();
//super();
//super(3);
System.out.println("zi..."+x);
}
}
class ExtendsDemo4
{
public static void main(String[] args)
{
Zi z = new Zi(0);
System.out.println(z.num);
}
}
当代码执行到 Zi z = new Zi(0);是因为 new Zi(0)是带参数的所以会执行Zi类中的带参构造方法
Zi(int x) // 被调用 打印结果为 Zi...0 第四步
{
this();
//super();
//super(3);
System.out.println("zi..."+x);
}
又因为带参zi构造方法中有this();那么就不会产生默认的super(),这时就会调用zi中不带参数的构造方法
Zi()
{
//super(); 这里你也注释了,默认在子类构造函数第一行有个调用父类无参构造函数: 第一步
//super(4);
System.out.println("zi run");
}
这个构造方法中是有默认的super()就会调用Fu类中的不带参数构造方法来完成父类的初始化。
作者:
王川
时间:
2013-4-4 14:08
创建子类对象的时候,首先默认调用父类的无参构造方法,所以首先是fu run,
然后因为是new zi(0),所以调用子类的有参构造方法,你在有参构造里又调用了子类的无参构造(this()),所以,出现zi run,
执行完无参构造方法,又回到有参构造里执行打印的代码。
而后你调用变量num,子类中是没有的,所以实际上是用的继承自父类的num
作者:
打工人
时间:
2013-4-4 16:31
若还有问题,继续追问; 没有的话,尽量及时将帖子分类改成【已解决】~
作者:
杨成
时间:
2013-4-4 23:55
Zi(){ }里面第一句有一个隐式的super(); 这个就等价于Fu();
顺序:
Zi(int x) -> Zi() -> Fu() 最后执行main()中的是 System.out.println(z.num); //输出的是在Fu()中已经将num改为60的结果。
作者:
王梦南
时间:
2013-4-6 14:39
本帖最后由 王梦南 于 2013-4-6 14:41 编辑
class Fu //extends Object
{
int num ;
Fu()
{
//super();
num= 60;
System.out.println("fu run");
}
Fu(int x)
{
System.out.println("fu ...."+x);
}
}
class Zi extends Fu
{
Zi()//创建子类对象,会先调用父类构造函数。没有显示写出调用父类哪个构造方法,默认调用无参的
{
//super();
//super(4);
System.out.println("zi run");
}
Zi(int x)
{
this();//this()是调用子类的无参构造方法,如果想调用父类无参构造函数应该用super();
//super();
//super(3);
System.out.println("zi..."+x);
}
}
class ExtendsDemo4
{
public static void main(String[] args)
{
Zi z = new Zi(0);//初始化子类,调用子类1个参数的构造方法
System.out.println(z.num);
}
}
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2