这个问题在这里已经有答案了:
为什么java不允许重写静态方法(22个答案)
四年前关门了。
public class Base {
private static boolean goo = true;
protected static boolean foo() {
goo = !goo;
return goo;
}
public String bar = "Base:" + foo();
public static void main(String[] args) {
Base base = new Sub();
System.out.println("Base:"+ base.foo());
}
}
public class Sub extends Base {
public String bar = "Sub:" + foo();
protected static boolean foo() {
return false;
}
}
为什么输出是“base:true”?foo()似乎是一个重写方法,所以动态类型是sub,那么为什么返回的输出不是“false”,并且base的字段有一个字符串,不应该有它的输出吗?
3条答案
按热度按时间3wabscal1#
在java中,不能重写静态方法,如果在子类中重新定义超类方法的静态方法,那么它就变成了方法重写(方法隐藏),而不是重写。
在您的示例中,您使用超类ref(base)调用它,因此超类方法只调用而不是子类方法。所以输出是“base:true”
如果您用非静态方法更改它,那么子类方法将被执行。
这里的规则是:超类ref和子类object将用于非静态方法。
rkue9o1l2#
方法重写用于重写子类的对象行为,不适用于静态方法。没有理由为静态方法支持此功能。此外,您不需要创建对象来访问静态方法。您可以简单地通过名称[foo()]来引用它,或者使用classname作为前缀[例如:sub.foo()]。
至于在输出中返回true的原因,这是因为您已经在类中使用了below语句,该语句调用foo()方法
public String bar = "Base:" + foo();
因为goo是一个静态变量,所以这个类只维护这个变量的一个示例。在执行上述语句时,goo的值变为false(goo=!goo
,顾一开始是真的)。稍后,当你使用
base.foo()
,将执行基类的foo()[因为方法重写不适用于静态方法,并且正在使用基类引用],这将再次还原goo的值,使其为真。htrmnn0y3#
当用方法或变量来处理“静态”这个词时,它指的是方法或变量属于“类”,而不是它的对象。
当没有对象时,就没有重写。
在类库中,您声明了main()方法,并在其中编写了以下语句。
现在,引用变量类型是base,对象类型是sub。因为foo()是静态方法,所以它属于声明引用变量的类(即base)。因此,调用类基类的foo方法。