为什么不可能重写静态方法?
如果可能,请举例说明。
为什么不可能重写静态方法?
如果可能,请举例说明。
当前回答
通过重写,我们可以根据对象类型创建一个多态性质。静态方法与对象无关。因此java不支持静态方法重写。
其他回答
重写依赖于类的实例。多态性的意义在于,您可以子类化一个类,而实现这些子类的对象对于父类中定义的相同方法将具有不同的行为(并且在子类中被重写)。静态方法不与类的任何实例相关联,因此这个概念不适用。
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.
现在看到上面的答案,每个人都知道我们不能重写静态方法,但不应该误解从子类访问静态方法的概念。
我们可以通过子类引用访问超类的静态方法,如果这个静态方法没有被子类中定义的新静态方法所隐藏。
例如,请参见下面的代码:-
public class StaticMethodsHiding {
public static void main(String[] args) {
SubClass.hello();
}
}
class SuperClass {
static void hello(){
System.out.println("SuperClass saying Hello");
}
}
class SubClass extends SuperClass {
// static void hello() {
// System.out.println("SubClass Hello");
// }
}
输出:
SuperClass saying Hello
关于在子类中隐藏静态方法的细节,请参阅Java oracle文档并搜索你可以在子类中做什么。
谢谢
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.
下面的代码表明这是可能的:
class OverridenStaticMeth {
static void printValue() {
System.out.println("Overriden Meth");
}
}
public class OverrideStaticMeth extends OverridenStaticMeth {
static void printValue() {
System.out.println("Overriding Meth");
}
public static void main(String[] args) {
OverridenStaticMeth osm = new OverrideStaticMeth();
osm.printValue();
System.out.println("now, from main");
printValue();
}
}
静态方法被JVM视为全局方法,根本不绑定到对象实例。
如果可以从类对象中调用静态方法(就像在Smalltalk等语言中那样),那么在概念上是可能的,但在Java中却不是这样。
EDIT
你可以重载静态方法,没关系。但是你不能重写静态方法,因为类不是一级对象。您可以使用反射在运行时获取对象的类,但所获得的对象并不与类层次结构并行。
class MyClass { ... }
class MySubClass extends MyClass { ... }
MyClass obj1 = new MyClass();
MySubClass obj2 = new MySubClass();
ob2 instanceof MyClass --> true
Class clazz1 = obj1.getClass();
Class clazz2 = obj2.getClass();
clazz2 instanceof clazz1 --> false
你可以对类进行反射,但它仅限于此。使用clazz1.staticMethod()不会调用静态方法,而是使用MyClass.staticMethod()。静态方法不绑定到对象,因此在静态方法中没有this或super的概念。静态方法是一个全局函数;因此,也没有多态性的概念,因此,方法重写没有意义。
但是,如果MyClass在运行时是一个调用方法的对象,这是可能的,就像在Smalltalk(或者可能是一个评论建议的JRuby,但我对JRuby一无所知)。
哦是的…还有一件事。您可以通过对象obj1.staticMethod()调用静态方法,但这实际上是MyClass.staticMethod()的语法糖,应该避免。在现代IDE中,它通常会引发一个警告。我不知道他们为什么允许走这条捷径。