为什么我们不能重写派生类中的静态方法



可能重复:
我们可以重写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意味着您正在子类中编写另一个静态方法,而不仅仅是重写基类方法。

最新更新