关于oop:为什么静态方法在Java中没有被覆盖?

Why static methods are not overridden in Java?

本问题已经有最佳答案,请猛点这里访问。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class A{

    public static void staticMethod(){
     System.out.println("Static method of A");
    }
}

class B extends A{

    public static void staticMethod(){
     System.out.println("Static method of B");
    }
}

class TestStaticOverride{

    public static void main(String args[]){
     B b=new B();
     A a=b;
     a.staticMethod();
    }
}

输出为"A的静态方法"。所以静态方法不会被重写,否则输出将是"B的静态方法"。在运行时,JVM如何决定调用类A而不是B的静态方法。


静态方法在编译时被解析,这就是为什么它们被绑定到一个定义了它们的类,而不是一个实例。所以它们属于一个类,而不是一个实例,这就是为什么另一个名称是"类方法"。您可以根据Java语法从实例调用静态方法,但从类调用它时,总是会考虑它。

1
2
3
A a;
a = [no matter what];
a.static_method();

与以下内容完全相同:

1
A.static_method()

不管你给"a"指定了什么值。


编辑:无论是通过实例还是在类级别调用静态方法,编译器都会将其识别为静态方法,因此在类级别而不是对象级别处理它。这意味着该方法将不知道从中调用该方法的对象的状态。如果使用一个对象来调用方法,例如在您的示例中,编译器将因此只能根据该对象被声明为什么,知道要调用哪个方法,a或b。如果它被实例化为一个不同的子类,那就不重要了,因为它是一个静态方法,并且没有对象的概念。所以,在您的示例中,这就是为什么它将调用A的静态方法而不是B的。

希望这能更清楚地解释我以前的经历


这是一个糟糕的实践,因为JVM不理解您试图给出的指令,而且想象一下您的OO会有多糟糕?

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class A{

public static void met(){
System.out.println("Class A");
}
}

class B extends A{

//Override
public static void met(){
System.out.println("Class B");
}

}

let's make a Polymorphism:

A a=new A();
A b=new B();

a.meth();//Class A
b.meth();//Class A !!! <===(Was Expected to be Class B)

尽管可能,但不建议从实例调用静态方法。

1
2
A a = new B();
a.staticMethod();

一个好的实践是直接从它所在的地方调用它:

1
A.staticMethod();

注意:我认为您可以在您的IDE中配置警告消息。

在stackoverflow的静态标记中可以看到:

Static is a term used in some programming languages to define a
function or data storage area (field) that is not bound to any
specific object instance.


不能重写静态方法。如果在staticMethod()中删除static,则在调用a.staticMethod()时,将调用b类中的staticMethod()。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class A {
public void staticMethod() {
    System.out.println("Static method of A");
}
}

class B extends A {
    public void staticMethod() {
        System.out.println("Static method of B");
    }
}

class Main {
    public static void main(String args[]) {
        B b = new B();
        A a = b;
        a.staticMethod();
    }
}

// Result: Static method of B

换句话说,如果您试图重写静态方法,那么将调用超级类中的方法。