英文:
Why child class constructor when initializing parent's part used overrided version of method?
问题
为什么在使用类B中定义的覆盖方法print()初始化部分类A时要使用```B()```?
预期输出:
A
4
实际输出:
0
4
public class Test
{
public static void main(String[] args)
{
new B();
}
}
class A
{
public A()
{
print();
}
public void print()
{
System.out.println("A");
}
}
class B extends A
{
int a = 4;
public B()
{
print();
}
@Override
public void print()
{
System.out.println(a);
}
}
英文:
Why B()
when initializing part of class A using overrides method print()
defined in class B?
Expected output:
A
4
Real output:
0
4
public class Test
{
public static void main(String[] args)
{
new B();
}
}
class A
{
public A()
{
print();
}
public void print()
{
System.out.println("A");
}
}
class B extends A
{
int a = 4;
public B()
{
print();
}
@Override
public void print()
{
System.out.println(a);
}
}
答案1
得分: 0
你已经在类B
中重写了print
方法。
因此,如果你在类B
的实例上调用print
,它将始终调用B
类中的方法。
这种情况甚至会发生在构造函数仍在运行时,这可能是你没有预料到的,它也可能会引起问题,因为B
类中并非所有字段都可能已经初始化。因此,从构造函数中调用任何非final
方法是不良实践。
你的示例很好地演示了这一点:
你说你预期第一个打印语句的输出是"A",大多数人可能会预期输出是"4",但实际上发生的是输出"0",因为字段B.a
尚未初始化。
public A()
{
print();
}
在这里,print()
不是一个静态方法,因此它等同于this.print()
。尽管你在类A
的构造函数中,但这是作为new B()
的一部分从B
的构造函数中调用的,所以此时的this
是B
类的一个实例(在B
的构造函数尚未完全完成其工作时)。
英文:
You have overriden print
in class B
.
So if you call print
on an instance of B
it will always go there.
This also happens while a constructor is still running, which you seem to not have expected, and it can also cause problem because not all fields in B
may have been initialized yet. For this reason, it is bad practice to call any method from a constructor that is not final
.
Your example nicely demonstrates that:
You say you expected to output of "A" for that first print statement, most people would have expected the output of "4", but what really happens is you get a "0" because the field B.a
is not yet initialized.
public A()
{
print();
}
Here, print()
is not a static method, so this is short for this.print()
. And even though you are in the constructor of class A
, this was being called as part of new B()
from the constructor of B
, so this
is an instance of B
(at a point of time when the constructor of B
has not yet fully done its work).
专注分享java语言的经验与见解,让所有开发者获益!
评论