Java继承时的初始化过程:
1. 父类对象内存分配
2. 父类字段默认初始化
3. 子类对象内存分配
4. 子类字段默认初始化
5. 进入父类构造-> 父类成员显示初始化(定义字段时设置的字段初值)
-> 执行父类构造体(此时可以调用抽象方法,所有父类字段已初始
化完毕,但子类字段尚未进行显示初始化)
6. 进入子类构造-> 子类成员显示初始化(定义字段时设置的字段初值)
-> 执行子类构造体(此时所有字段已经显示初始化)
第一种输出结果为
Hello World
21
hello world
22
第二种情况下输出的居然是
Hello World
01
hello world
12
分析过程:
1, 程序充main进入程序后先对对父类和子类的属性默认赋值,int默认为0,此时super.i=0 this.i=0
2, 然后进入父类的构造函数 ,对父类的属性显示赋值,此时super.i=2
3, 打印”this+”1”” 注意:this是父类的一个引用,指向子类的对象,相当于是this.toString(),调用子类的toString()
4, 第一种情况:运行子类的toString(),调用父类的toString(),得到换回值为super.2,打印21
第二种情况:运行子类的toString(),换回子类的i值,此时子类i值还没有显性赋值,所以为0,打印为01
5, 进入子类的构造函数,对子类的属性显性赋值,此时this.i=1
6, 第一种情况:运行子类的toString(),调用父类的toString(),得到换回值为super.2,打印22
第二种情况:运行子类的toString(),换回子类的i值,此时子类i值已经显性赋值,所以为1,打印为12。
1. 父类对象内存分配
2. 父类字段默认初始化
3. 子类对象内存分配
4. 子类字段默认初始化
5. 进入父类构造-> 父类成员显示初始化(定义字段时设置的字段初值)
-> 执行父类构造体(此时可以调用抽象方法,所有父类字段已初始
化完毕,但子类字段尚未进行显示初始化)
6. 进入子类构造-> 子类成员显示初始化(定义字段时设置的字段初值)
-> 执行子类构造体(此时所有字段已经显示初始化)
package com.jwh.cn;
public class ExtendsRun extends HelloWorld{
public int i=1;
public ExtendsRun() {
super();
System.out.println("hello world");
System.out.println(this+"2");
}
public static void main(String[] args) {
ExtendsRun er = new ExtendsRun();
}
@Override
public String toString() {
return super.toString(); //第一种情况
// return new Integer(i).toString(); //第二种情况
}
}
class HelloWorld{
public int i=2;
public HelloWorld() {
System.out.println("Hello World");
System.out.println(this+"1"); //this在此相当于this.toString(),是一个父类的应用,指向子类的对象
}
@Override
public String toString() {
return new Integer(i).toString();
}
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
第一种输出结果为
Hello World
21
hello world
22
第二种情况下输出的居然是
Hello World
01
hello world
12
分析过程:
1, 程序充main进入程序后先对对父类和子类的属性默认赋值,int默认为0,此时super.i=0 this.i=0
2, 然后进入父类的构造函数 ,对父类的属性显示赋值,此时super.i=2
3, 打印”this+”1”” 注意:this是父类的一个引用,指向子类的对象,相当于是this.toString(),调用子类的toString()
4, 第一种情况:运行子类的toString(),调用父类的toString(),得到换回值为super.2,打印21
第二种情况:运行子类的toString(),换回子类的i值,此时子类i值还没有显性赋值,所以为0,打印为01
5, 进入子类的构造函数,对子类的属性显性赋值,此时this.i=1
6, 第一种情况:运行子类的toString(),调用父类的toString(),得到换回值为super.2,打印22
第二种情况:运行子类的toString(),换回子类的i值,此时子类i值已经显性赋值,所以为1,打印为12。