Java 压倒一切;“静态”;方法/字段,带“;“非静态”;方法/字段

Java 压倒一切;“静态”;方法/字段,带“;“非静态”;方法/字段,java,inheritance,static,static-methods,Java,Inheritance,Static,Static Methods,在这里,如果我试图重写一个静态方法而不在子类中使用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 giv

在这里,如果我试图重写一个静态方法而不在子类中使用
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 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();
    }
}
会发生什么?是否应该调用
A
的实现,因为
b
A
引用?还是应该调用
B
的实现,因为
B
B
对象

因为这两个选项同样有效,所以不允许允许实例方法“重写”
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的方法。所以如果你运行这个 课堂测试{

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

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

重写不适用于字段。您不能重写静态方法,而是隐藏它们。我的问题是,为什么静态变量不会发生这种情况?即静态变量可以被重写(隐藏)不使用带变量的static。阅读我的最后两句话。无论变量是否为static,它们都适用