java-当我在构造函数中调用一个方法时会发生什么?

标签 java constructor polymorphism overriding

class Glyph {
    void draw() {
        print("Glyph.draw()");
    }

    Glyph() {
        print("Glyph() before draw()");
        draw();
        print("Glyph() after draw()");
    }

}
class RoundGlyph extends Glyph{
    private int radius = 1;
    RoundGlyph(int r){
        radius = r;
        print("RoundGLyph.draw(), radius = " + radius);
    }
    void draw(){
        print("radius:" + radius);
    }
    public static void main(String[] args){
        new RoundGlyph(5);

    }

}

//Glyph() before draw()
radius:0
Glyph() after draw()
RoundGLyph.draw(), radius = 5

代码如上。

由于 draw() 不是静态的,因此必须为其指定一个隐式参数 (this)。而在这种情况下,在 Glyph 的构造函数中调用了 draw(),所以我想知道这个“隐式参数”是什么。 据我所知,当我使用类型为 T 的 t 调用 t.f() 时,编译器会将其转换为 T.f(t)。

结果表明,在我看来,作为此参数提供的是一个 RoundGlyph。但这怎么可能呢?显然,调用 draw() 时不会创建 RoundGlyph。

最佳答案

您正在构造一个 RoundGLyph 实例。 RoundGLyph 的构造函数调用父类(super class)的构造函数 - Glyph - 它调用 draw() 方法。由于 RoundGLyph 覆盖了 Glyphdraw() 方法,因此 Glyph 构造函数调用 RoundGLyph draw() 方法,打印radius 的值。

但是,由于是在RoundGLyph实例完全初始化之前调用的(RoundGLyph构造函数体还没有执行,连radius = 1 初始化尚未执行),radius 变量仍然保持默认值 0。由于 Java 语言的这种行为,建议不要在构造函数中调用非 final方法(因为它们可以被覆盖)。

关于java-当我在构造函数中调用一个方法时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43571181/

相关文章:

c# - 如何在 .NET 7 中使用 System.Text.Json 序列化多级多态类型层次结构?

C++ - 填充派生类数据成员,同时设置基类属性值

java - 检测用户代理以重定向到struts 2中的特定Jsp

c++ - 在对象数组的每个索引上调用不同的构造函数

c++ - 如何从喜欢的列表中制作复制构造函数

c# - 多线程和构造函数完整性

c# - 如何在不同层次的多态类之间保持一对一的关系?

java - 如何找到 com.bitbar.recorder.extensions.ExtSolo 的 jar?

java - 为什么我在 java 代码中得到下一个输出? (假真)

java - 使用 TimeZone 和 ZoneId 类的时区 ID 之间的差异