当我尝试覆盖静态方法时,为什么编译器没有抱怨?

34 java static-methods overriding

我知道我们不能在Java中覆盖静态方法,但有人可以解释下面的代码吗?

class A {
    public static void a() { 
        System.out.println("A.a()");
    }
}   

class B extends A {
    public static void a() {
        System.out.println("B.a()");
    }
}
Run Code Online (Sandbox Code Playgroud)

我怎么能a()在课堂上覆盖方法B

gob*_*ice 54

你没有在这里覆盖任何东西.为了自己看一下,尝试在课@Override前放入注释,Java会抛出错误.public static void a()B

你刚才定义在类中的函数B称为a()从功能,这是不同的(毫无关系)a()A.

但是,因为B.a()它与父类中的函数具有相同的名称,所以它隐藏了 A.a() [如Eng所指出的那样].福阿德.在运行时,编译器使用声明的引用的实际类来确定要运行的方法.例如,

B b = new B();
b.a() //prints B.a()

A a = (A)b;
a.a() //print A.a(). Uses the declared reference's class to find the method.
Run Code Online (Sandbox Code Playgroud)

您无法在Java中覆盖静态方法.请记住static方法和字段与类关联,而不是与对象关联.(虽然,在某些语言中,如Smalltalk,这是可能的).

我在这里找到了一些好的答案:为什么Java不允许覆盖静态方法?

  • 你声称静态方法不是继承的,但如果我从`B`中删除`a()`然后`Ba();`突然打印"Aa()".您继承了静态方法,但不要覆盖它们.相反,你将它们隐藏为Eng.Fouad在他的回答中提到的. (6认同)

Eng*_*uad 9

这就是所谓的hiding a method,如Java教程中所述,覆盖和隐藏方法:

如果子类定义的类方法与超类中的类方法具有相同的签名,则子类中的方法会隐藏超类中的方法.

  • @goblinjuice这是Java中隐藏*的*字面定义. (2认同)

Jig*_*shi 6

static方法不是继承的,所以它B的方法的单独副本

static与... class的状态无关Object

  • 这是错误的,你继承了静态方法,但是在子类中声明另一个具有相同签名的方法的机制称为隐藏,并且稍微不同,然后覆盖. (6认同)