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.f()时,t为t类型,编译器会将其变为T.f(t)。
结果表明,在我看来,它是一个RoundGlyph作为这个参数提供。但是这怎么可能?显然,调用draw()时不会创建RoundGlyph。
答案 0 :(得分:6)
您正在构建RoundGLyph
实例。 RoundGLyph
的构造函数调用超类的构造函数 - Glyph
- 调用draw()
方法。由于RoundGLyph
会覆盖Glyph
draw()
方法,Glyph
构造函数会调用RoundGLyph
draw()
方法,该方法会打印{ {1}}。
但是,由于在radius
实例完全初始化之前调用它(RoundGLyph
构造函数的主体尚未执行,甚至RoundGLyph
初始化也没有&#39}。尚未执行),radius = 1
变量仍保留默认值radius
。由于Java语言的这种行为,建议不要在构造函数中调用非final方法(因为它们可以被覆盖)。
答案 1 :(得分:1)
将正常调用方法。这次指向的对象是不完美的,但是这个指针在那里,所以没有异常,但建议不要这样做,因为在不完美的对象上调用实例方法是危险的。
答案 2 :(得分:0)
在这种情况下,正在调用超级构造函数,即调用Glyph构造函数。现在发生的棘手的事情是调用drawG(方法)在RoundGlyph中被覆盖,因此Glyph调用RoundGlyph中的覆盖版本,打印半径变量,但同样奇怪的是,0被打印出来因为子构造函数语句直到现在才执行,所以因为它是一个基元,所以打印默认值0。如果它是某个对象,那么就会打印出null。希望这能澄清它。