为什么不可能重写静态方法?

如果可能,请举例说明。


当前回答

Overriding in Java simply means that the particular method would be called based on the runtime type of the object and not on the compile-time type of it (which is the case with overridden static methods). As static methods are class methods they are not instance methods so they have nothing to do with the fact which reference is pointing to which Object or instance, because due to the nature of static method it belongs to a specific class. You can redeclare it in the subclass but that subclass won't know anything about the parent class' static methods because, as I said, it is specific to only that class in which it has been declared. Accessing them using object references is just an extra liberty given by the designers of Java and we should certainly not think of stopping that practice only when they restrict it more details and example http://faisalbhagat.blogspot.com/2014/09/method-overriding-and-method-hiding.html

其他回答

简单的解决方案:使用单例实例。它将允许重写和继承。

在我的系统中,我有SingletonsRegistry类,它为传递的class返回实例。如果没有找到instance,则创建它。

Haxe语言类:

package rflib.common.utils;
import haxe.ds.ObjectMap;



class SingletonsRegistry
{
  public static var instances:Map<Class<Dynamic>, Dynamic>;

  static function __init__()
  {
    StaticsInitializer.addCallback(SingletonsRegistry, function()
    {
      instances = null;
    });

  } 

  public static function getInstance(cls:Class<Dynamic>, ?args:Array<Dynamic>)
  {
    if (instances == null) {
      instances = untyped new ObjectMap<Dynamic, Dynamic>();      
    }

    if (!instances.exists(cls)) 
    {
      if (args == null) args = [];
      instances.set(cls, Type.createInstance(cls, args));
    }

    return instances.get(cls);
  }


  public static function validate(inst:Dynamic, cls:Class<Dynamic>)
  {
    if (instances == null) return;

    var inst2 = instances[cls];
    if (inst2 != null && inst != inst2) throw "Can\'t create multiple instances of " + Type.getClassName(cls) + " - it's singleton!";
  }

}

重写依赖于类的实例。多态性的意义在于,您可以子类化一个类,而实现这些子类的对象对于父类中定义的相同方法将具有不同的行为(并且在子类中被重写)。静态方法不与类的任何实例相关联,因此这个概念不适用。

There were two considerations driving Java's design that impacted this. One was a concern with performance: there had been a lot of criticism of Smalltalk about it being too slow (garbage collection and polymorphic calls being part of that) and Java's creators were determined to avoid that. Another was the decision that the target audience for Java was C++ developers. Making static methods work the way they do had the benefit of familiarity for C++ programmers and was also very fast, because there's no need to wait until runtime to figure out which method to call.

Yes. Practically Java allows overriding static method, and No theoretically if you Override a static method in Java then it will compile and run smoothly but it will lose Polymorphism which is the basic property of Java. You will Read Everywhere that it is not possible to try yourself compiling and running. you will get your answer. e.g. If you Have Class Animal and a static method eat() and you Override that static method in its Subclass lets called it Dog. Then when wherever you Assign a Dog object to an Animal Reference and call eat() according to Java Dog's eat() should have been called but in static Overriding Animals' eat() will Be Called.

class Animal {
    public static void eat() {
        System.out.println("Animal Eating");
    }
}

class Dog extends Animal{
    public static void eat() {
        System.out.println("Dog Eating");
    }
}

class Test {
    public static void main(String args[]) {
       Animal obj= new Dog();//Dog object in animal
       obj.eat(); //should call dog's eat but it didn't
    }
}


Output Animal Eating

According to Polymorphism Principle of Java, the Output Should be Dog Eating. But the result was different because to support Polymorphism Java uses Late Binding that means methods are called only at the run-time but not in the case of static methods. In static methods compiler calls methods at the compile time rather than the run-time, so we get methods according to the reference and not according to the object a reference a containing that's why You can say Practically it supports static overring but theoretically, it doesn't.

方法重写可以通过动态调度实现,这意味着对象的声明类型不决定其行为,而是决定其运行时类型:

Animal lassie = new Dog();
lassie.speak(); // outputs "woof!"
Animal kermit = new Frog();
kermit.speak(); // outputs "ribbit!"

尽管lassie和kermit都声明为Animal类型的对象,但它们的行为(method .speak())会有所不同,因为动态调度只会在运行时将方法调用.speak()绑定到实现,而不是在编译时。

现在,这里是静态关键字开始有意义的地方:单词“静态”是“动态”的反义词。所以你不能重写静态方法的原因是因为静态成员上没有动态分派——因为静态字面上的意思是“非动态的”。如果它们是动态分派的(因此可以被重写),静态关键字就没有意义了。

I like and double Jay's comment (https://stackoverflow.com/a/2223803/1517187). I agree that this is the bad design of Java. Many other languages support overriding static methods, as we see in previous comments. I feel Jay has also come to Java from Delphi like me. Delphi (Object Pascal) was one of the languages implementing OOP before Java and one of the first languages used for commercial application development. It is obvious that many people had experience with that language since it was in the past the only language to write commercial GUI products. And - yes, we could in Delphi override static methods. Actually, static methods in Delphi are called "class methods", while Delphi had the different concept of "Delphi static methods" which were methods with early binding. To override methods you had to use late binding, declare "virtual" directive. So it was very convenient and intuitive and I would expect this in Java.