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

时间:2013-05-17 20:31:33

标签: java static-methods method-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()");
    }
}

我如何能够覆盖班级a()中的方法B

8 个答案:

答案 0 :(得分:54)

你没有在这里覆盖任何东西。要亲眼看看,请尝试在@Override public static void a()之前将B注释放在类B中,Java会抛出错误。

您刚刚在类a()中定义了一个名为a()的函数,该函数与类A中的函数B.a()截然不同(无关系)。

但是因为A.a()与父类中的函数具有相同的名称,所以隐藏 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. [由Eng指出。福阿德。在运行时,编译器使用声明的引用的实际类来确定要运行的方法。例如,

static

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

我在这里找到了一些好的答案:Why doesn't Java allow overriding of static methods?

答案 1 :(得分:9)

这称为hiding a method,如Java教程Overriding and Hiding Methods中所述:

  

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

答案 2 :(得分:6)

static方法未被继承,因此其B方法的单独副本

staticclass有关,而与Object

的状态无关

答案 3 :(得分:3)

您没有覆盖方法a(),因为static方法未被继承。如果你放了@Override,你就会看到错误。

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

但这并不能阻止你在两个类中定义具有相同签名的静态方法。

答案 4 :(得分:2)

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

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被声明为A,因此会调用A.a()

答案 5 :(得分:1)

您的方法不是重写方法。你只是尝试在派生类的方法之前放置@Override注释。它会给你一个编译时错误。所以java不允许你覆盖静态方法。

答案 6 :(得分:1)

虽然接受了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.

答案 7 :(得分:0)

静态方法将通过其类名称调用,因此我们不需要创建类对象,我们只需使用类名称来调用它,因此我们无法覆盖静态

例如

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();

表示无法覆盖静态类 如果它被覆盖,那么如何调整它。