动态绑定,重写

oewdyzsn  于 2021-07-03  发布在  Java
关注(0)|答案(3)|浏览(474)

这个问题在这里已经有答案了

为什么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的字段有一个字符串,不应该有它的输出吗?

3wabscal

3wabscal1#

在java中,不能重写静态方法,如果在子类中重新定义超类方法的静态方法,那么它就变成了方法重写(方法隐藏),而不是重写。
在您的示例中,您使用超类ref(base)调用它,因此超类方法只调用而不是子类方法。所以输出是“base:true”
如果您用非静态方法更改它,那么子类方法将被执行。
这里的规则是:超类ref和子类object将用于非静态方法。

rkue9o1l

rkue9o1l2#

方法重写用于重写子类的对象行为,不适用于静态方法。没有理由为静态方法支持此功能。此外,您不需要创建对象来访问静态方法。您可以简单地通过名称[foo()]来引用它,或者使用classname作为前缀[例如:sub.foo()]。
至于在输出中返回true的原因,这是因为您已经在类中使用了below语句,该语句调用foo()方法 public String bar = "Base:" + foo(); 因为goo是一个静态变量,所以这个类只维护这个变量的一个示例。在执行上述语句时,goo的值变为false( goo=!goo ,顾一开始是真的)。
稍后,当你使用 base.foo() ,将执行基类的foo()[因为方法重写不适用于静态方法,并且正在使用基类引用],这将再次还原goo的值,使其为真。

htrmnn0y

htrmnn0y3#

当用方法或变量来处理“静态”这个词时,它指的是方法或变量属于“类”,而不是它的对象。
当没有对象时,就没有重写。
在类库中,您声明了main()方法,并在其中编写了以下语句。

Base base = new Sub();
System.out.println("Base:"+ base.foo());

现在,引用变量类型是base,对象类型是sub。因为foo()是静态方法,所以它属于声明引用变量的类(即base)。因此,调用类基类的foo方法。

相关问题