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

如果可能,请举例说明。


当前回答

通过重写,可以实现动态多态。 当您说覆盖静态方法时,您试图使用的词语是矛盾的。

静态表示-编译时,重写用于动态多态性。 两者在性质上是相反的,因此不能同时使用。

动态多态行为发生在程序员使用对象并访问实例方法时。JRE将根据您使用的对象类型映射不同类的不同实例方法。

当你说覆盖静态方法时,我们将使用类名访问静态方法,它将在编译时被链接,因此没有在运行时将方法与静态方法链接的概念。因此,术语“重写”静态方法本身没有任何意义。

注意:即使你用一个对象访问一个类方法,java编译器仍然有足够的智能来发现它,并会做静态链接。

其他回答

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

Here is a simple explanation. A static method is associated with a class while an instance method is associated with a particular object. Overrides allow calling the different implementation of the overridden methods associated with the particular object. So it is counter-intuitive to override static method which is not even associated with objects but the class itself in the first place. So static methods cannot be overridden based on what object is calling it, it will always be associated with the class where it was created.

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.

在Java(和许多面向对象语言,但我不能说所有;所有的方法都有一个固定的签名——参数和类型。在虚方法中,第一个参数是隐含的:对对象本身的引用,当从对象内部调用时,编译器会自动添加这个参数。

静态方法没有区别——它们仍然有固定的签名。然而,通过将方法声明为静态,您已经显式地声明了编译器不能在该签名的开头包含隐含的对象形参。因此,任何其他调用此方法的代码都不能试图将对象引用放到堆栈上。如果它确实这样做了,那么方法执行将无法工作,因为参数将在堆栈上的错误位置—移位1。

由于两者之间的差异;虚方法总是有一个上下文对象的引用(即this),这样就可以引用堆中属于该对象实例的任何东西。但是对于静态方法,由于没有传递引用,该方法不能访问任何对象变量和方法,因为上下文是未知的。

如果您希望Java更改定义,以便为每个方法(静态方法或虚拟方法)传递对象上下文,那么实际上您将只有虚拟方法。

就像有人在评论中问的那样——你想要这个功能的原因和目的是什么?

I do not know Ruby much, as this was mentioned by the OP, I did some research. I see that in Ruby classes are really a special kind of object and one can create (even dynamically) new methods. Classes are full class objects in Ruby, they are not in Java. This is just something you will have to accept when working with Java (or C#). These are not dynamic languages, though C# is adding some forms of dynamic. In reality, Ruby does not have "static" methods as far as I could find - in that case these are methods on the singleton class object. You can then override this singleton with a new class and the methods in the previous class object will call those defined in the new class (correct?). So if you called a method in the context of the original class it still would only execute the original statics, but calling a method in the derived class, would call methods either from the parent or sub-class. Interesting and I can see some value in that. It takes a different thought pattern.

由于您正在使用Java工作,您将需要适应这种做事方式。他们为什么这么做?好吧,可能是为了提高当时的性能基于现有的技术和理解。计算机语言在不断发展。回顾过去,并没有OOP这种东西。在未来,还会有其他新的想法。

EDIT: One other comment. Now that I see the differences and as I Java/C# developer myself, I can understand why the answers you get from Java developers may be confusing if you are coming from a language like Ruby. Java static methods are not the same as Ruby class methods. Java developers will have a hard time understanding this, as will conversely those who work mostly with a language like Ruby/Smalltalk. I can see how this would also be greatly confusing by the fact that Java also uses "class method" as another way to talk about static methods but this same term is used differently by Ruby. Java does not have Ruby style class methods (sorry); Ruby does not have Java style static methods which are really just old procedural style functions, as found in C.

顺便说一下,谢谢你的问题!今天我学到了一些关于类方法的新知识(Ruby风格)。

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

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.