我知道我们不能覆盖 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
?
我知道我们不能覆盖 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
?
You didn't override anything here. To see for yourself, Try putting @Override
annotation before public static void a()
in class B
and Java will throw an error.
You just defined a function in class B
called a()
, which is distinct (no relation whatsoever) from the function a()
in class A
.
But Because B.a()
has the same name as a function in the parent class, it hides A.a()
[As pointed by Eng. Fouad]. At runtime, the compiler uses the actual class of the declared reference to determine which method to run. For example,
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.
You cannot override static methods in Java. Remember static
methods and fields are associated with the class, not with the objects. (Although, in some languages like Smalltalk, this is possible).
I found some good answers here: Why doesn't Java allow overriding of static methods?
这就是所谓的hiding a method
,如 Java 教程Overriding and Hiding Methods中所述:
如果子类定义了与超类中的类方法具有相同签名的类方法,则子类中的方法会隐藏超类中的方法。
static
methods are not inherited so its B
's separate copy of method
static
are related to class
not the state of Object
You didn't override the method a()
, because static
methods are not inherited. If you had put @Override
, you would have seen an error.
A.java:10: error: method does not override or implement a method from a supertype
@Override
^
1 error
But that doesn't stop you from defining static methods with the same signature in both classes.
此外,调用方法的选择取决于变量的声明类型。
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()
被调用。
您的方法不是被覆盖的方法。您只是尝试在派生类中的方法之前放置 @Override 注释。它会给你一个编译时错误。所以java不允许你覆盖静态方法。
虽然 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。
静态方法将通过其类名调用,因此我们不需要创建类对象,我们只需使用类名调用它,因此我们不能覆盖静态
例如
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();
意味着静态类如果被覆盖则不能被覆盖,那么如何调用它。
静态成员属于类而不属于任何对象。因此静态方法不能被覆盖。覆盖也发生在运行时,因此编译器不会抱怨。
但是,您可以将 @Override 注释添加到方法中。这将标记编译器错误。