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

如果可能,请举例说明。


当前回答

静态方法被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中,它通常会引发一个警告。我不知道他们为什么允许走这条捷径。

其他回答

重写是为实例成员保留的,以支持多态行为。静态类成员不属于特定实例。相反,静态成员属于类,因此不支持重写,因为子类只继承受保护和公共实例成员,而不继承静态成员。您可能希望定义一个接口,并研究工厂和/或策略设计模式,以评估替代方法。

静态方法被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中,它通常会引发一个警告。我不知道他们为什么允许走这条捷径。

重写静态方法有什么好处呢?不能通过实例调用静态方法。

MyClass.static1()
MySubClass.static1()   // If you overrode, you have to call it through MySubClass anyway.

编辑:似乎由于语言设计中的一个不幸疏忽,您可以通过实例调用静态方法。一般没人会这么做。我的坏。

静态方法、变量、块或嵌套类属于整个类而不是对象。

Java中的方法用于公开对象/类的行为。在这里,由于方法是静态的(即静态方法仅用于表示类的行为),改变/覆盖整个类的行为将违反面向对象编程的基本支柱之一,即高内聚。(记住构造函数在Java中是一种特殊的方法。)

高内聚性——一个类应该只有一个角色。例如:car类应该只生成汽车对象,而不生成自行车、卡车、飞机等。但是Car类可能有一些只属于它自己的特性(行为)。

因此,在设计java编程语言时。语言设计者认为,只有通过使方法本质上是静态的,才能允许开发人员保留类的某些行为。


下面的代码尝试覆盖静态方法,但不会遇到任何编译错误。

public class Vehicle {
static int VIN;

public static int getVehileNumber() {
    return VIN;
}}

class Car extends Vehicle {
static int carNumber;

public static int getVehileNumber() {
    return carNumber;
}}

这是因为,在这里我们没有重写一个方法,而只是重新声明它。Java允许重新声明一个方法(静态/非静态)。

从Car类的getVehileNumber()方法中删除静态关键字将导致编译错误,因为,我们正在尝试改变只属于Vehicle类的静态方法的功能。

此外,如果getVehileNumber()被声明为final,那么代码将无法编译,因为final关键字限制程序员重新声明方法。

public static final int getVehileNumber() {
return VIN;     }

总的来说,这取决于软件设计人员在哪里使用静态方法。 我个人更喜欢使用静态方法来执行某些操作,而不需要创建类的任何实例。第二,对外界隐藏一个类的行为。

下面的代码表明这是可能的:

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();

}   

}