关于构造器内部的多态方法的行为
在java编程思想这本书中有一小节讲:构造器内部的多态方法行为,源码如下:
class Glyph{
void draw(){syste.out.println("Glyph.draw()");
Glyph(){
system.out.println("Glyph() before draw()");
draw();
system.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
private 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 RolyConstructors {
public static void main(string[] args){
new RoundGlyph(5);
}
}
输出的结果如下:
Glyph() after draw()
RoundGlyph.draw(), radius = 0;
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5
在类Glyph的构造函数中调用了一个draw()方法,这个方法的调用最终是指向了子类RoundGlyph中的draw()方法,调用这个方法用的字节码指令为invokevirtual,在<深入理解java虚拟机>(周志明)这本书中写到了多态的本质是invokevirtual调用的方法在运行时会找到操作数栈的第一元素所指的实际类型.那么在本段代码中,类Glyph的构造函数中调用draw()方法的时候,是怎么指向RoundGlyph类的?,操作数栈顶第一个元素指是什么?我只知道在局部变更表的第一个元素是this.
这个问题想了两天了,一直是不得其解,希望高人指点迷经.
多态 虚拟机 java 栈 class --------------------编程问答--------------------
class Glyph{
void draw(){syste.out.println("Glyph.draw()");
Glyph(){
system.out.println("Glyph() before draw()");
draw();
system.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
private int radius = 1;
RoundGlyph(int r){
super() // compiler 自动加载call父类的构造器
radius = r;
system.out.println("RoundGlyph.RoundGLyph(), radius = " + radius);
}
void draw(){
super.draw() // 调用父类的draw()方法
system.out.println("RoundGlyph.draw(), radius = " + radius);
}
}
public class RolyConstructors {
public static void main(string[] args){
new RoundGlyph(5);
}
}
因为 draw() 方法被overridden, 所以会调用子类的draw() --------------------编程问答-------------------- Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGLyph(), radius = 5
首先运行结果是上面的这个……
new RoundGlyph(5);
1.这段代码运行时会先访问其父类 Glyph的构造函数:
System.out.println("Glyph() before draw()"); 打印输出
2.然后draw();会执行被子类RoundGlyph覆写的draw()方法
此时radius还没有被赋初值,默认为0,因此打印出 RoundGlyph.draw(), radius = 0
3.继续执行之后的System.out.println("Glyph() after draw()"); 打印输出
4.父类的构造函数结束,执行本类RoundGlyph的构造函数
radius = r;
System.out.println("RoundGlyph.RoundGLyph(), radius = " + radius);
给radius赋值5,后输出
程序流程是这样的,要上升到栈啊、堆啊的就要等大神回复你了 --------------------编程问答-------------------- java 多态内存布局不懂,帮顶 --------------------编程问答--------------------
我就不明白为什么会找到子类的draw(),是如何找到的? --------------------编程问答--------------------
可否在深入点? --------------------编程问答--------------------
也就是java多态的实现原理?嗯,我找了篇文章,你看下
http://www.cnblogs.com/stonehat/archive/2012/04/30/2476798.html
或者你也可以再百度下“java多态原理”,只能帮你到这里了 --------------------编程问答--------------------
动态绑定原理如下:
假如一个对象O是class C1, C2,...Cn-1, Cn的实例,其中C1是C2的子类,C2是C3的子类。。。以此类推,Cn-1是Cn的子类,也就是说Cn是最笼统的一个类,而C1是最细致的一个类。 如果实例O调用方法P,JVM就会从C1 - CN 中搜索P的实现,也就是说从最细致的一个类开始搜索直到最笼统的一个类。一旦有一个实现被找到,JVM就会调用P方法的这个实现。 --------------------编程问答--------------------
class Glyph{
void draw(){System.out.println("Glyph.draw()");}
Glyph(){
System.out.println("Glyph() before draw()");
System.out.println(this.getClass()); //1111111
this.draw(); //2222222 加了this
System.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
private 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 RolyConstructors {
public static void main(String[] args){
new RoundGlyph(5);
System.out.println("-------------------------");//333333
new Glyph(); //444444
}
}
加了4行代码,楼主运行一下就知道咯 --------------------编程问答--------------------
class Glyph{
void draw(){System.out.println("Glyph.draw()");}
Glyph(){
System.out.println("Glyph() before draw()");
System.out.println(this.getClass()); //1111111
this.draw(); //2222222 加了this
System.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
private 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 RolyConstructors {
public static void main(String[] args){
new RoundGlyph(5);
System.out.println("-------------------------");//333333
new Glyph(); //444444
}
}
加了4行代码,楼主运行一下就知道咯
在Glyph中的构造函数的this指向的是roundGlyph,那这样的话,与invokevirtual就能对应起来了,我在想这个方法的的this为什么是Roundglyph,是不是类Roundglyph在调用构造函数的时候,会在自己的构造函数中选调用父类的构造函数,这样的话,父类的构造函数在子类中? --------------------编程问答--------------------
class Glyph{
void draw(){System.out.println("Glyph.draw()");}
Glyph(){
System.out.println("Glyph() before draw()");
System.out.println(this.getClass()); //1111111
this.draw(); //2222222 加了this
System.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
private 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 RolyConstructors {
public static void main(String[] args){
new RoundGlyph(5);
System.out.println("-------------------------");//333333
new Glyph(); //444444
}
}
加了4行代码,楼主运行一下就知道咯
在Glyph中的构造函数的this指向的是roundGlyph,那这样的话,与invokevirtual就能对应起来了,我在想这个方法的的this为什么是Roundglyph,是不是类Roundglyph在调用构造函数的时候,会在自己的构造函数中选调用父类的构造函数,这样的话,父类的构造函数在子类中?
子类在被实例化的时候首先调用父类的构造方法,你说的是对的;
而这个this为什么指向子类,很简单啊,this代表的是对象实例,在你的代码中Glyph类没有被实例化,仅仅是它的子类被实例化了,所以this才指向roundGlyph类的对象啊。
你看看我加的第4行代码,创建Glyph类对象的运行结果,this不就指向他自己了吗。。。。 --------------------编程问答--------------------
class Glyph{
void draw(){System.out.println("Glyph.draw()");}
Glyph(){
System.out.println("Glyph() before draw()");
System.out.println(this.getClass()); //1111111
this.draw(); //2222222 加了this
System.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
private 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 RolyConstructors {
public static void main(String[] args){
new RoundGlyph(5);
System.out.println("-------------------------");//333333
new Glyph(); //444444
}
}
加了4行代码,楼主运行一下就知道咯
在Glyph中的构造函数的this指向的是roundGlyph,那这样的话,与invokevirtual就能对应起来了,我在想这个方法的的this为什么是Roundglyph,是不是类Roundglyph在调用构造函数的时候,会在自己的构造函数中选调用父类的构造函数,这样的话,父类的构造函数在子类中?
子类在被实例化的时候首先调用父类的构造方法,你说的是对的;
而这个this为什么指向子类,很简单啊,this代表的是对象实例,在你的代码中Glyph类没有被实例化,仅仅是它的子类被实例化了,所以this才指向roundGlyph类的对象啊。
你看看我加的第4行代码,创建Glyph类对象的运行结果,this不就指向他自己了吗。。。。
这里面有个问题,子类并没有被实例化 --------------------编程问答--------------------
class Glyph{
void draw(){System.out.println("Glyph.draw()");}
Glyph(){
System.out.println("Glyph() before draw()");
System.out.println(this.getClass()); //1111111
this.draw(); //2222222 加了this
System.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
private 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 RolyConstructors {
public static void main(String[] args){
new RoundGlyph(5);
System.out.println("-------------------------");//333333
new Glyph(); //444444
}
}
加了4行代码,楼主运行一下就知道咯
在Glyph中的构造函数的this指向的是roundGlyph,那这样的话,与invokevirtual就能对应起来了,我在想这个方法的的this为什么是Roundglyph,是不是类Roundglyph在调用构造函数的时候,会在自己的构造函数中选调用父类的构造函数,这样的话,父类的构造函数在子类中?
子类在被实例化的时候首先调用父类的构造方法,你说的是对的;
而这个this为什么指向子类,很简单啊,this代表的是对象实例,在你的代码中Glyph类没有被实例化,仅仅是它的子类被实例化了,所以this才指向roundGlyph类的对象啊。
你看看我加的第4行代码,创建Glyph类对象的运行结果,this不就指向他自己了吗。。。。
这里面有个问题,子类并没有被实例化
子类没有实例化,你在搞笑吗?? --------------------编程问答--------------------
class Glyph{
void draw(){System.out.println("Glyph.draw()");}
Glyph(){
System.out.println("Glyph() before draw()");
System.out.println(this.getClass()); //1111111
this.draw(); //2222222 加了this
System.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
private 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 RolyConstructors {
public static void main(String[] args){
new RoundGlyph(5);
System.out.println("-------------------------");//333333
new Glyph(); //444444
}
}
加了4行代码,楼主运行一下就知道咯
在Glyph中的构造函数的this指向的是roundGlyph,那这样的话,与invokevirtual就能对应起来了,我在想这个方法的的this为什么是Roundglyph,是不是类Roundglyph在调用构造函数的时候,会在自己的构造函数中选调用父类的构造函数,这样的话,父类的构造函数在子类中?
子类在被实例化的时候首先调用父类的构造方法,你说的是对的;
而这个this为什么指向子类,很简单啊,this代表的是对象实例,在你的代码中Glyph类没有被实例化,仅仅是它的子类被实例化了,所以this才指向roundGlyph类的对象啊。
你看看我加的第4行代码,创建Glyph类对象的运行结果,this不就指向他自己了吗。。。。
这里面有个问题,子类并没有被实例化
子类没有实例化,你在搞笑吗??
不是我搞笑,在调用父类构造函数的时候,还没有调用子类的构造函数。 --------------------编程问答--------------------
class Glyph{
void draw(){System.out.println("Glyph.draw()");}
Glyph(){
System.out.println("Glyph() before draw()");
System.out.println(this.getClass()); //1111111
this.draw(); //2222222 加了this
System.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
private 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 RolyConstructors {
public static void main(String[] args){
new RoundGlyph(5);
System.out.println("-------------------------");//333333
new Glyph(); //444444
}
}
加了4行代码,楼主运行一下就知道咯
在Glyph中的构造函数的this指向的是roundGlyph,那这样的话,与invokevirtual就能对应起来了,我在想这个方法的的this为什么是Roundglyph,是不是类Roundglyph在调用构造函数的时候,会在自己的构造函数中选调用父类的构造函数,这样的话,父类的构造函数在子类中?
子类在被实例化的时候首先调用父类的构造方法,你说的是对的;
而这个this为什么指向子类,很简单啊,this代表的是对象实例,在你的代码中Glyph类没有被实例化,仅仅是它的子类被实例化了,所以this才指向roundGlyph类的对象啊。
你看看我加的第4行代码,创建Glyph类对象的运行结果,this不就指向他自己了吗。。。。
这里面有个问题,子类并没有被实例化
子类没有实例化,你在搞笑吗??
我理解有点问题了,应该是在堆里已分配了空间,初始化成了默认值。
补充:Java , Java SE