对于下面的代码,我得到了输出
In Base.foo()
In Derived.bar()
代码:
class Base {
public static void foo(Base bObj) {
System.out.println("In Base.foo()");
bObj.bar();
}
public void bar() {
System.out.println("In Base.bar()");
}
}
class Derived extends Base {
public static void foo(Base bObj) {
System.out.println("In Derived.foo()");
bObj.bar();
}
public void bar() {
System.out.println("In Derived.bar()");
}
}
class OverrideTest {
public static void main(String []args) {
Base bObj = new Derived();
bObj.foo(bObj);
}
}
代码如何流动?我如何得到如上所述的输出。我困惑一点,寻找解释。
答案 0 :(得分:3)
不会覆盖静态方法,也没有虚拟调用。
在Derived
课程中,static foo
方法隐藏其父类“static foo
方法。
但是,在main
方法中,您在引用类型foo
上调用Base
,因此Base#foo
被调用(因此它会打印"In Base.foo()"
) 。
反过来,静态方法在传递的对象上调用bar
, IS-A Base
,但恰好是Derived
的实例。
由于bar
是实例方法,并且在签名匹配的情况下被覆盖,因此调用将解析为实例类型Derived
,因此"In Derived.bar()"
打印出来。
备注强>
@Override
注释。
这将无法为您的foo
方法编译,因为它是静态的,因此清楚地指出那里没有可能的重写。 static
方法(即更喜欢明确的ClassName.staticMethod
习语),因为这可能会导致混淆调用方法的范围。 答案 1 :(得分:0)
代码流程就像
Base bObj = new Derived();
在这里,您要创建类型为Base的bObj,运行时对象将是Derived类。
bObj.foo(BOBJ);
因为foo()是一个静态方法,静态绑定发生在编译时,因此它不会检查运行时对象类型。因此,当您声明一个Base类型对象时,Base中的方法将被执行。在该函数内部你用对象参数调用非静态方法bar()。在运行时传递的对象是你的Derived类实例,因此它将被调用。