动态绑定,覆盖

时间:2016-05-10 05:24:12

标签: java override

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的字段也有一个字符串,不应该在那里是它的输出?

3 个答案:

答案 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 方法。