对于下面的代码,我得到的输出是
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);
}
}
代码如何流动?我如何获得上述输出。我有点困惑,正在寻找解释。
最佳答案
静态方法不会被覆盖,没有虚拟调用。
在您的Derived
类中,static foo
方法隐藏其父类的static foo
方法。
但是,在您的 main
方法中,您在引用类型 Base
上调用 foo
,因此 Base#foo
被调用(所以它打印 "In Base.foo()"
)。
反过来,静态方法在传递的对象上调用bar
,该对象IS-A Base
,但恰好是派生
。
由于 bar
是一个实例方法并且被覆盖,因为您的签名匹配,调用解析为实例类型,即Derived
,因此打印了 "In Derived.bar()"
。
注意事项
- 一个好的做法是在覆盖的方法上使用
@Override
注释。 这将无法为您的foo
方法编译,因为它是静态的,因此清楚地指出那里不可能被覆盖。 - 另一个好的做法(如 Jon Skeet 所指出的)是避免在实例对象上调用
static
方法(即更喜欢显式的ClassName.staticMethod
习语),因为这可能会导致调用该方法的范围困惑。
关于java - 代码如何在方法覆盖中流动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35058712/