0

编辑:没关系,我想通了。由于该方法是静态的,它只查看变量的编译时类型,它的实例化并没有什么区别。

class Parent {
    void sayIt() {
        System.out.println("Miss ");
    }
}
class Child extends Parent {
    static void sayIt() {
        System.out.println("Hit ");
    }
    public static void main(String args[]) {
        Parent papa = new Parent();
        papa.sayIt();
        Child kid = new Child();
        kid.sayIt();
        papa = kid;
        papa.sayIt();
        kid = (Child)papa;
        kid.sayIt();
    }
}

这将打印“Miss Hit Hit Hit”。我明白怎么做。但是,如果我将sayIt()方法更改为静态:

class Parent {
    static void sayIt() {
        System.out.println("Miss ");
    }
}
class Child extends Parent {
    static void sayIt() {
        System.out.println("Hit ");
    }
    public static void main(String args[]) {
        Parent papa = new Parent();
        papa.sayIt();
        Child kid = new Child();
        kid.sayIt();
        papa = kid;
        papa.sayIt();
        kid = (Child)papa;
        kid.sayIt();
    }

现在它打印“Hit Miss Hit Miss”。

我无法弄清楚为什么会发生这种情况。有什么线索吗?

4

3 回答 3

0

Parent papa = new Parent();-- 代表父类,你有静态方法。当您尝试在引用上调用静态方法时,它不会查看它所拥有的对象。

检查这里,添加这两行并测试它。

 Parent p = null;
        p.sayIt();

您看不到 NPE,它会调用您的静态方法。

于 2013-10-28T08:02:35.550 回答
0

首先,问题不应该是继承静态方法。继承不适用于静态方法。

您不必创建实例来访问静态方法。

使用Parent.sayIt()- 用于访问用 Parent.java 编写的静态方法

用途Child.sayIt()- 用于访问用 Child.java 编写的静态方法

于 2013-10-28T07:51:09.747 回答
0

静态方法依赖于引用类型而不是对象类型。papa.sayIt();总是打印Miss,因为编译器会将其替换为Parent.sayIt();. 关于第一种情况,您实际上是隐藏了父方法而不是覆盖它。

请参阅:覆盖与隐藏 Java - 困惑

于 2013-10-28T07:52:09.820 回答