当前位置: 技术问答>java相关
关于初始化及构建器问题,谁帮助我???
来源: 互联网 发布时间:2015-05-14
本文导语: abstract class Glyph{ int radius=2;//该句注释 abstract void draw(); Glyph(){ System.out.println("Glyph() before draw()"); draw(); System.out.println("Glyph() after draw()"); } } class RoundGlyph extends Glyph{ int radius=1; RoundGlyph(int r){ ...
abstract class Glyph{
int radius=2;//该句注释
abstract void draw();
Glyph(){
System.out.println("Glyph() before draw()");
draw();
System.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph{
int radius=1;
RoundGlyph(int r){
radius=r;
System.out.println("RoundGlyph.RoundGlyph(),radius= "+radius);
}
void draw(){
System.out.println("RoundGlyph.draw(),radius= "+radius);
}
}
public class PolyConstructors {
public static void main(String[] args)
{
new RoundGlyph(6);
}
}
输出结果为:
Glyph() before draw()
RoundGlyph.draw(),radius= 0
Glyph() after draw()
RoundGlyph.RoundGlyph(),radius= 6
为什么会这样呢?而如果把注释的那一行注释后,运行结果为:
Glyph() before draw()
RoundGlyph.draw(),radius= 2
Glyph() after draw()
RoundGlyph.RoundGlyph(),radius= 6
请问原因?
int radius=2;//该句注释
abstract void draw();
Glyph(){
System.out.println("Glyph() before draw()");
draw();
System.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph{
int radius=1;
RoundGlyph(int r){
radius=r;
System.out.println("RoundGlyph.RoundGlyph(),radius= "+radius);
}
void draw(){
System.out.println("RoundGlyph.draw(),radius= "+radius);
}
}
public class PolyConstructors {
public static void main(String[] args)
{
new RoundGlyph(6);
}
}
输出结果为:
Glyph() before draw()
RoundGlyph.draw(),radius= 0
Glyph() after draw()
RoundGlyph.RoundGlyph(),radius= 6
为什么会这样呢?而如果把注释的那一行注释后,运行结果为:
Glyph() before draw()
RoundGlyph.draw(),radius= 2
Glyph() after draw()
RoundGlyph.RoundGlyph(),radius= 6
请问原因?
|
下面简单说一下构造器在子类实例生成中的调用:对于你这个问题我有几点先说明一下:
(1)java中函数有两种:static函数和非static函数(也就是c++中的虚拟函数)。注意java 中没有c++中那种叫nostatic member function的函数类型。
(2)java中虚拟函数引用机制使用太多了,包括构造器中都是一样使用虚拟函数引用机制的。(这个是c++中不是这样的情况)
下面就你说的问题,具体说一下:
(1)一个带有父类的子类实例的构造过程。
简单说明,一些不太相关细节被省略。
(a)分配实例内存空间,并且内存空间清空置“零”。
(b)初始化父类的静态初始化部分(函数先,变量后)
(c)初始化子类的静态初始化部分
(d)初始化父类的非静态部分
(e)调用父类的构造器
(f)初始化子类的非静态部分
(g)调用子类的构造器
到这里子类实例就可以认为生成构造成功了
(1)java中函数有两种:static函数和非static函数(也就是c++中的虚拟函数)。注意java 中没有c++中那种叫nostatic member function的函数类型。
(2)java中虚拟函数引用机制使用太多了,包括构造器中都是一样使用虚拟函数引用机制的。(这个是c++中不是这样的情况)
下面就你说的问题,具体说一下:
(1)一个带有父类的子类实例的构造过程。
简单说明,一些不太相关细节被省略。
(a)分配实例内存空间,并且内存空间清空置“零”。
(b)初始化父类的静态初始化部分(函数先,变量后)
(c)初始化子类的静态初始化部分
(d)初始化父类的非静态部分
(e)调用父类的构造器
(f)初始化子类的非静态部分
(g)调用子类的构造器
到这里子类实例就可以认为生成构造成功了
|
现在具体到你的问题:
我们这样理解一个事实;
就是子类构造器中可以调用父类中的默认构造器,
不过这个问题有很多情况,我这里只是简单说一种。
但是从编译器的角度(这点跟c++中有些不同,你要是不想知道区别就不用管了),
父类构造器在子类中被自动扩展了,就象内联(inline)函数一样,所以当程序到了引用父类构造器的时候(参见下面的步骤),引用的是子类的函数draw,当然变量也是子类的了。
值得特别注意的时候,这个时候子类的非静态变量只是被置“零”,还没有被初始化,所以就只有是“零”(或者是相当与“零”的值)。
于是你的程序结果就是一样的。不过如果你要是使用静态变量的话,结果会不太一样。
我们这样理解一个事实;
就是子类构造器中可以调用父类中的默认构造器,
不过这个问题有很多情况,我这里只是简单说一种。
但是从编译器的角度(这点跟c++中有些不同,你要是不想知道区别就不用管了),
父类构造器在子类中被自动扩展了,就象内联(inline)函数一样,所以当程序到了引用父类构造器的时候(参见下面的步骤),引用的是子类的函数draw,当然变量也是子类的了。
值得特别注意的时候,这个时候子类的非静态变量只是被置“零”,还没有被初始化,所以就只有是“零”(或者是相当与“零”的值)。
于是你的程序结果就是一样的。不过如果你要是使用静态变量的话,结果会不太一样。
|
首先说一下我的测试效果:
我在win2000/jdk1.4环境下面测试,无论父类中那行注释与否,结果都是一样的。
Glyph() before draw()
RoundGlyph.draw(),radius= 0
Glyph() after draw()
RoundGlyph.RoundGlyph(),radius= 6
我在win2000/jdk1.4环境下面测试,无论父类中那行注释与否,结果都是一样的。
Glyph() before draw()
RoundGlyph.draw(),radius= 0
Glyph() after draw()
RoundGlyph.RoundGlyph(),radius= 6