调用超类构造函数的子类方法
public class A {
String bar = "A.bar";
A() { foo(); }
public void foo() {
System.out.println("A.foo(): bar = " + bar);
}
}
public class B extends A {
String bar = "B.bar";
B(){ foo(); }
public void foo(){
System.out.println("B.foo(): bar = " + bar);
}
}
public class C {
public static void main(String[] args){
A a = new B();
System.out.println("a.bar = " + a.bar);
a.foo();
}
}
为什么第一个输出有bar = null? 是否因为在创建类B之前调用了B.foo()?如果是,那么怎么来B.foo()可以被调用? 还是因为B.foo()中的字段栏试图从A获取栏字段,但无法访问它?调用超类构造函数的子类方法
我的问题是不同的一个链接,我不问有关呼叫顺序,我问为什么第一个输出为空?另一个问题不是关于字段或空变量。
我不明白,在B.foo酒吧变量如何为null,如果在A和B中
定义起初,我想告诉你的是,可变条在类一个完全不同于其他变量barB。
可能是你想,他们是这样的一个变量:
public class B extends A{
public B(){
bar = "B.bar";´
foo();
}
void foo(){
System.out.println("B.foo bar ="+ bar);
}
}
,你将有结果:
B.foo bar =A.bar
B.foo bar =B.bar
a.bar=B.bar
B.foo bar =B.bar
时不告诉是请,并且我还会为您描述您的特殊情况(为什么bar = null)
的原因,第一个是打印是B.foo(): bar=null
因为当你调用线A a = new B();
正在发生的事情是,你创建B
类型的对象,这就要求B
类型的对象的构造函数。但是,该构造函数对构造函数A
的“隐藏”super
调用。问题是B
类尚未创建(您现在正在创建类A
的过程中),因此它们的参数(例如bar
)未初始化,这意味着它们被分配了null
值。由于对动态功能的调用是通过动态调度来完成的,因此您仍然可以获得B.foo():
,因此调用B
的函数foo
。只有在调用A
的构造函数后,才能调用B
的构造函数,然后初始化B
的变量 - 包括bar
。
好吧,我会同意,如果富是静态的,但它不是如此,我不明白它如何可以调用foo如果没有B的实例。 – Raz
@Raz因为你不初始化方法。该方法属于“B”类。动态调度机制试图调用“A”的'foo',但是当它“看到”对象的动态类型是'B'类型时,它只是调用'B'的'foo'方法。 – Mickey
我试图看看在类已经初始化之前是否可以调用类的方法。和我发现这个问题https://stackoverflow.com/questions/2394205/can-i-use-methods-of-a-class-without-instantiating-this-class其中说,你不能 – Raz
的可能的复制[在什么顺序来在Java中的静态/实例初始化语句块运行?](https://stackoverflow.com/questions/2007666/in-what-order-do-static-instance-initializer-blocks-in-java-run) – Tom
请将代码粘贴为* text *而不是图片。 –