使用"non-static"方法/字段覆盖"static"方法/字段



如果我试图在子类中不使用static而重写静态方法,它会给我一个错误。而这不是静态变量的情况。为什么?

class A {
    static int a;
    static void a() {
       System.out.println("in A");
    }
}

class B extends A {
    int a=9;/*this does not give an error*/
    void a()/*this statement gives an error*/ {
       System.out.println("In B"+(A.a));
    }
}

class Test {
    public static void main(String []args) {   
        B b1=new B();
        b1.a();         
    }
}

字段不可重写。

它与Java命名作用域有关。Java可以用比方法更少的歧义来解析字段名。

在B中,JVM不知道您是想调用A.a()还是B.a()

答案是:静态应用于方法意味着您可以在不实例化该类对象的情况下访问该方法,应用于变量意味着您不能在代码中修改该变量。在addiction中,override并不关心实际要重写的方法中的变量。这是因为override正在用一种新方法替换该方法。伪代码示例

 Class Triangle {
     public method calcArea() {
          // generic method
      }
 }
 Class RightTriangle extend Triangle {
      public method calcArea() {
           // area needs to be calculated in different way, so I specify a new Area method
      }
 }
 Class Main {
      public Main() {
           Triangle a;
           RigthTriangle b;
           a.calcArea(); // Calling Triangle.area!
           b.calcArea(); // calling RightTriangle.area!
      }
 }               

静态方法不显示运行时多态性。因此,根据规则,静态方法在编译时解析。通过将方法声明为static,您隐藏了它。所以子类看不到它。但这是可能的。

class A {
    static void test() {
        System.out.println("A");
    }
}
class B extends A {
    static void test() {
        System.out.println("B");
    }
}

这是因为B中的test()是B的方法,A中的test()是编译器理解的A的方法。如果你运行这个类Test {

public static void main(String []args) {   
    B b1=new A();
    b1.test();         
}

在编译时看到b1编译器的引用类型知道你正在调用B的测试,即使在运行时对象将是A的

这是因为由于一些奇怪的原因,static方法实际上可以通过引用调用。要调用的静态方法是基于引用的类型而不是对象的类型,这意味着允许具有与static方法相同签名的实例方法将在调用哪个方法时产生歧义。

例如,如果允许:

class A {
    static void method() {
        System.out.println("A");
    }
}
class B extends A {
    void method() {
        System.out.println("B");
    }
}
class Main {
    public static void main(String[] args) {
        A b = new B();
        b.method();
    }
}

会发生什么?由于bA的引用,应该调用A的实现吗?还是应该调用B的实现,因为bB对象?

因为这两个选项同样有效,所以不允许实例方法"覆盖"static方法,以确保所有方法调用都是有效的。


现在,对于字段(静态和非静态)这不是真的,因为字段不能在子类中被覆盖,只能被隐藏。所以编译器可以很容易地根据引用的类型找出你想要的字段。

最新更新