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,而不是为什么返回输出不是"#34; false",而且Base的字段也有一个字符串,不应该在那里是它的输出?
答案 0 :(得分:1)
在java中,你不能覆盖静态方法,如果在子类中重新定义超类方法的静态方法,那么它将成为覆盖方法(方法隐藏),而不是覆盖。
在您的示例中,您使用超类ref(base)调用它,因此超类方法仅调用而不是子类方法。所以输出是" Base:true"
如果使用非静态方法更改它,则将执行子类方法。
这里的规则是:超类ref和子类对象适用于非静态方法。
答案 1 :(得分:0)
方法重写用于覆盖子类的对象行为,不适用于静态方法。没有理由支持静态方法的此功能。此外,您不需要创建对象来访问静态方法。您可以通过名称[foo()]简单地引用它,或使用classname作为前缀[例如:Sub.foo()]。
至于为什么在输出中返回true,这是因为你已经在你的类中使用了下面的语句,它调用了foo()方法
public String bar = "Base:" + foo();
由于goo是一个静态变量,因此只为该类维护此变量的一个实例。并且在执行上述语句时,goo的值更改为false(goo=!goo
,goo最初为true)。
稍后,当您使用base.foo()
时,将执行基类的 foo() [因为方法覆盖不适用于静态方法并且正在使用基类引用]恢复goo的价值使其成为现实。
答案 2 :(得分:0)
当你在方法或变量方面处理“静态”这个词时,它指的是方法或变量属于“类”而不属于它的对象。
当没有物体时,没有覆盖。
在您的班级基础中,您声明了main()方法,您在其中编写了以下语句。
Base base = new Sub();
System.out.println("Base:"+ base.foo());
现在,参考变量类型为 Base ,对象类型为 Sub 。由于 foo() 是静态方法,因此它属于声明引用变量的类(即 Base )。 因此,会调用类 Base 的 foo 方法。