int num = 8;
{
System.out.println("cons code num = " + num);
}
Zi(){
System.out.println("cons function num = " + num);
}
void show(){
System.out.println("zi show num = " + num);
}
}
class Student{
public static void main(String[] args){
new Zi();
}
}
输出结果为:
zi show num = 0
cons code num = 8
cons function num = 8
为什么是这样!我原以为是3个8 这代表了第一个输出的时候未执行num赋值语句。作者: 朱盛文 时间: 2013-3-13 20:25 本帖最后由 朱盛文 于 2013-3-13 20:44 编辑
class Fu
{
Fu(){
show(); //3,Fu类调用show()方法,因为是在Zi类中加载父类,所以先在Zi类中找show()方法,如果Zi类中没有show()方法,就在Fu类中找。
}
void show(){
System.out.println("fu show run");
}
}
class Zi extends Fu{ //2,Zi类继承Fu类,跳到Fu类,加载Fu类的构造函数。
int num = 8; //5,接下来加载Zi类成员变量并初始化,此时num = 8 。
{
System.out.println("cons code num = " + num);//6,加载Zi类构造代码块,打印cons code num =8 。构造代码块先于构造函数加载。
}
Zi(){
System.out.println("cons function num = " + num);//7,加载Zi类构造函数,打印cons function num = 8 。
}
void show(){ //4,调用Zi类的show()方法,此时num还未初始化,所以是默认值 0 ,打印zi show num = 0 。
System.out.println("zi show num = " + num);
}
}
class Student
{
public static void main(String[] args)
{
new Zi(); //1,创建Zi类对象,加载在堆内存中。
}
}
所以控制台上打印出来的是:
zi show num = 0
cons code num =8
cons function num = 8
作者: 黑马-郑玉元 时间: 2013-3-13 20:37
构造代码块最先运行,构造代码块存放在静态域,随着类的加载而加载,优先执行!所以第一行输出是zi show num = 0
然后后面的执行过程你知道了吧??作者: 刘国涛 时间: 2013-3-13 20:51
class Fu{
Fu(){
show();//子类覆盖了父类的show方法,所以调用子类的show方法,这时num还没有赋值,默认为0
}
void show(){
System.out.println("fu show run");
}
}
class Zi extends Fu{
int num = 8;//如果改成final int num=8;就会输出3个8
{
System.out.println("cons code num = " + num);//构造代码块优先于构造函数执行
}
Zi(){
System.out.println("cons function num = " + num);
}
void show(){
System.out.println("zi show num = " + num);
}
}
class Student{
public static void main(String[] args){
new Zi();
}
}作者: 樊玲 时间: 2013-3-13 21:10
class Fu{
Fu(){ //3.父类构造函数执行,在执行代码块里边的show()方法时,因为子类继承父类,虚拟机看到子 //类也有show()这个方法,所以就对父类的show()方法,进行了覆盖。因为子类自身还没有实例化。 //num依然为0.所以 Zi show num=0
show();
}
void show(){
System.out.println("fu show run");
}
}
class Zi extends Fu{
int num = 8;
{
System.out.println("cons code num = " + num);
}
Zi(){ // 2. 因为Zi类继承了Fu类。所以子类的构造函数,第一行,默认有super(),去调用
//父类的构造函数,所以就走到了父类的构造函数。便于子类实例化。
System.out.println("cons function num = " + num);
}
void show(){
System.out.println("zi show num = " + num);
}
}
class Student{
public static void main(String[] args){
new Zi(); //1.这里,创建对象的时候,首先要找Zi类的构造函数,进行初始化。
}
}
接下来就是子类自身实例化,就是正常的步骤啦,我就写在这里了,方便看得清楚。
刚刚不是说,调用父类构造函数,是为了子类进行实例化么。所以,父类构造函数执行完,就该子类,执行构造函数了。
这里有一点。有构造代码块的时候,是先于构造函数执行的。所以先执行构造代码块。即:cons code num =8
子类构造函数执行,即cons function num =8。
所以最后执行结果为:
zi show num = 0
cons code num =8
cons function num = 8作者: 王军行 时间: 2013-3-13 21:45
关键就是覆盖,父类的show方法被子类覆盖了。这里在父类构造函数中调用的已经是子类的方法了
但是java中初始化子类必先初始化父类,父类初始化时子类的num还没有初始化,所以打印出来的是0; 作者: 聂益飞 时间: 2013-3-13 21:55
黑马-郑玉元 发表于 2013-3-13 20:37
构造代码块最先运行,构造代码块存放在静态域,随着类的加载而加载,优先执行!所以第一行输出是zi show nu ...