动态绑定,覆盖
dynamic binding, overriding
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,而不是为什么 return 输出不是 "false",而且 Base 的字段有一个字符串,不应该有它的输出?
在java中,你不能覆盖静态方法,如果你在子class中重新定义super class方法的那个静态方法,那么它就变成方法覆盖(方法隐藏),而不是覆盖。
在您的示例中,您使用 super class ref(base) 调用它,因此仅调用 super class 方法而不调用 sub class 方法。所以输出是 "Base: true"
如果您使用非静态方法更改它,那么子 class 方法将被执行。
这里的规则是:super class ref 和 sub class 对象将适用于非静态方法。
方法覆盖用于覆盖子对象的行为class,不适用于静态方法。没有理由为静态方法支持此功能。此外,您不需要创建对象来访问静态方法。您可以简单地通过其名称[foo()] 或使用class名称作为前缀来引用它[例如:Sub.foo()].
就输出中返回 true 的原因而言,这是因为您已经在 class 中使用了以下语句,它调用了 foo() 方法
public String bar = "Base:" + foo();
因为 goo 是一个静态变量,所以只为这个 class 维护这个变量的一个实例。并且在执行上述语句时,goo 的值变为 false(goo=!goo
,goo 最初为 true)。
稍后,当您使用 base.foo()
时,基础 class 的 foo() 将被执行 [因为方法覆盖不适用于静态方法和Base class reference is being used] 再次恢复 goo 的值使其为真。
当您在方法或变量方面处理单词 "static" 时,它指的是该方法或变量属于 "class" 而不是其对象。
当没有对象时,就没有覆盖。
在您的 class Base 中,您声明了 main() 方法,您在其中编写了以下语句。
Base base = new Sub();
System.out.println("Base:"+ base.foo());
现在,引用变量类型为Base,对象类型为Sub。由于 foo() 是一个静态方法,它属于声明引用变量的 class (即 基础)。
因此,foo方法classBase 被调用。
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,而不是为什么 return 输出不是 "false",而且 Base 的字段有一个字符串,不应该有它的输出?
在java中,你不能覆盖静态方法,如果你在子class中重新定义super class方法的那个静态方法,那么它就变成方法覆盖(方法隐藏),而不是覆盖。
在您的示例中,您使用 super class ref(base) 调用它,因此仅调用 super class 方法而不调用 sub class 方法。所以输出是 "Base: true"
如果您使用非静态方法更改它,那么子 class 方法将被执行。
这里的规则是:super class ref 和 sub class 对象将适用于非静态方法。
方法覆盖用于覆盖子对象的行为class,不适用于静态方法。没有理由为静态方法支持此功能。此外,您不需要创建对象来访问静态方法。您可以简单地通过其名称[foo()] 或使用class名称作为前缀来引用它[例如:Sub.foo()].
就输出中返回 true 的原因而言,这是因为您已经在 class 中使用了以下语句,它调用了 foo() 方法
public String bar = "Base:" + foo();
因为 goo 是一个静态变量,所以只为这个 class 维护这个变量的一个实例。并且在执行上述语句时,goo 的值变为 false(goo=!goo
,goo 最初为 true)。
稍后,当您使用 base.foo()
时,基础 class 的 foo() 将被执行 [因为方法覆盖不适用于静态方法和Base class reference is being used] 再次恢复 goo 的值使其为真。
当您在方法或变量方面处理单词 "static" 时,它指的是该方法或变量属于 "class" 而不是其对象。
当没有对象时,就没有覆盖。
在您的 class Base 中,您声明了 main() 方法,您在其中编写了以下语句。
Base base = new Sub();
System.out.println("Base:"+ base.foo());
现在,引用变量类型为Base,对象类型为Sub。由于 foo() 是一个静态方法,它属于声明引用变量的 class (即 基础)。 因此,foo方法classBase 被调用。