可能重复:
我们可以重写Java中的静态方法吗?
我们不能重写基类的静态方法。
事实上,我试过这样的东西:
// Base class
public class StaticExampleImpl {
protected String name="overriding";
public static void display(){
System.out.println("static method display : base class");
}
}
则派生类如下:
//derived class
public class StaticDemo extends StaticExampleImpl {
// cannot override the static methods...
//@Override
public static void display(){
System.out.println("child!!! static method display");
}
public static void main(String[] args) {
StaticDemo d=new StaticDemo();
d.display(); // derived class display is called rather than Base class.
}
}
因此,当我取消对@Override
方法的注释时,它给出的错误是"静态方法不能被覆盖"。但有了评论,效果很好。因此,当我们创建对象并用实例调用静态方法时,这些方法可以很好地工作。那么有什么区别呢??
因为静态方法不会被继承。
当您取消对
@Override
的注释时,表示您正试图覆盖静态方法,这是不可能的,这就是为什么你得到错误但当你评论
//@Override
时,就意味着你在声明一个新的方法。
静态方法不属于类的实例,它属于实际的类。
当您调用d.display();
时,实际上是在调用StaticDemo d
引用的静态方法的静态方法。
如果你这样做了:
StaticExampleImpl d2 = new StaticDemo();d2.display()
,您会发现它调用基类的display。
但是,不要这样做。它会导致代码混乱,并且是一种糟糕的实现继承的方式。
Overriding
依赖于一个类的实例。polymorphism
是指您可以对一个类进行子类化,并且实现这些subclasses
的对象对于超类中定义的方法(以及子类中的overridden
)将具有不同的行为。static
方法不属于类的实例,因此该概念不适用。
静态方法不能继承。如果要调用"base"类静态方法,则必须显式调用StaticExampleImpl.display()
。
静态方法绑定到类,它们不能被继承,这就是为什么在派生类中不能有基类静态方法的原因。
如果您试图覆盖一个静态方法,那么您的设计可能有问题。
OOP和多态性允许您执行以下操作:
public class MyClass1 {
public String toString() { return "MyClass1 Instance"; }
}
public class MyClass2 extends MyClass1 {
@Override
public String toString() { return "MyClass1 Instance"; }
}
public void printSomething(MyClass1 myclass1){
System.out.println(myclass1);
}
在printSomething内部,将被调用的toString方法是myClass1运行时类型上的方法:当您在printSomehing内部传递MyClass2的实例时,它的编译类型将是myClass1,但它的运行时类型将是MyClass2
很明显,要使用多态性,您需要对象实例,其中实际的运行时类型可能与编译类型不同。但是,静态方法不属于任何对象实例,而是属于类。你为什么不向我们解释一下你正在努力实现的目标?
以下代码:
StaticExampleImpl one = new StaticExampleImpl();
StaticDemo two = new StaticDemo();
StaticExampleImpl three = two;
one.display();
two.display();
three.display();
将产生以下输出:
static method display : base class
child!!! static method display
static method display : base class
正如您所看到的,该方法不会被继承。这就是它们被称为"静态方法"的原因:它们被静态地调用,而不是像实例方法那样动态地调用。调用静态方法时,类的编译时类型才是最重要的,而不是运行时类型。
这也是为什么不应该通过对象实例调用静态方法的原因。总是这样称呼他们:
StaticExampleImpl.display();
StaticDemo.display();
这完全消除了当人们期望继承适用于这些方法时可能出现的混乱。
java中的任何静态块,都可能是静态变量,在加载类时加载方法。您可能知道java中的类加载器。所以事情就是静态块(方法、变量或任何静态的东西)被加载一次。因此,您实际上无法覆盖任何静态块。
注释@Override意味着您正在子类中编写另一个静态方法,而不仅仅是重写基类方法。