为什么不抱怨编译当我尝试覆盖静态方法?(Why doesn't the compiler c

2019-09-04 03:47发布

我知道,我们不能覆盖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()");
    }
}

我怎么能够覆盖方法a()B

Answer 1:

你没有覆盖此处任何东西。 要看到自己,尝试把@Override注释前public static void a()B和Java将抛出一个错误。

刚刚定义的函数的类B称为a()从函数,这是明显的(毫无关系) a()A

但由于Ba()具有相同的名称作为在父类中的功能,它隐藏 Aa() [正如指出由主机。 福阿德。 在运行时,编译器使用的实际类声明的参考来确定运行哪个方法。 例如,

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.

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

我发现了一些很好的答案在这里: 为什么不是Java允许的静态方法压倒一切的?



Answer 2:

这就是所谓的hiding a method ,作为Java教程说明重载和隐藏方法 :

如果子类定义了一类方法具有相同签名作为在超类中的一类方法中,在子类中的方法隐藏了一个超类中。



Answer 3:

static方法不能被继承所以它的B的分离方法的拷贝

static都跟class没有的状态Object



Answer 4:

你没有覆盖的方法a()因为static方法不能继承。 如果你已经把@Override ,你会看到一个错误。

A.java:10: error: method does not override or implement a method from a supertype
    @Override
    ^
1 error

但是,这并不从定义在两个类相同签名的静态方法阻止你。



Answer 5:

此外,方法的选择调用依赖于声明的类型变量。

B b = null;
b.a(); // (1) prints B.a()
A a = new B();
a.a(); // (2) prints a.a() 

在(1),如果系统关心的身份b ,它会抛出NPE 。 和在(2),的值a被忽略。 由于a被声明为AAa()被调用。



Answer 6:

你的方法不重写方法。 你只是试图把@Override注释您在派生类的方法之前。 它会给你一个编译时错误。 所以Java不会让你重写静态方法。



Answer 7:

虽然goblinjuice答案被接受,我想示例代码可以改进:

public class StaticTest {
    public static void main(String[] args) {
        A.print();
        B.print();
        System.out.println("-");

        A a = new A();
        B b = new B();
        a.print();
        b.print();
        System.out.println("-");

        A c = b;
        c.print();
    }
}

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

class B extends A {
    public static void print() {
        System.out.println("B");
    }
}

生产:

A
B
-
A
B
-
A

把B覆盖print()它会对最后一行写B中。



Answer 8:

静态方法将通过它的类名调用,所以我们并不需要创建类的对象,我们只是CAL它与类名,所以我们不能覆盖静态

例如

class AClass{
public static void test(){

 } 
}

class BClass extends AClass{
public static void test(){}

}

class CClass extends BClass{
public static void main(String args[]){

AClass aclass=new AClass();

aclass.test(); // its wrong because static method is called 
               // by its class name it can't accept object
}
}

我们只是把它

AClass.test();

如果它覆盖再怎么CAL这意味着静态类不能被重写。



文章来源: Why doesn't the compiler complain when I try to override a static method?