【问题标题】:Overriding "static" method/field with "non-static" method/field [duplicate]用“非静态”方法/字段覆盖“静态”方法/字段[重复]
【发布时间】:2014-06-25 21:12:35
【问题描述】:

如果我尝试在子类中不使用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 inheritance static static-methods


【解决方案1】:

字段不可覆盖。

它与 Java 命名范围有关。与方法相比,Java 解析字段名称的歧义性要小得多。

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

【讨论】:

    【解决方案2】:

    答案是: 应用于方法的静态意味着您可以在不实例化该类的对象的情况下访问该方法,应用于变量意味着您不能在代码中修改该变量。 上瘾的是,覆盖并不关心您实际覆盖的方法中的变量。 这是因为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!
          }
     }               
    

    【讨论】:

      【解决方案3】:

      静态方法不显示运行时多态性。所以按照规则,静态方法是在编译时解析的。通过声明一个静态方法,你隐藏了它。所以没有子类可以看到它。但这是可能的。

      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 的

      【讨论】:

        【解决方案4】:

        这是因为出于某种奇怪的原因,static 方法实际上可以通过引用来调用。要调用的静态方法是基于 reference 的类型而不是对象,这意味着允许使用与 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 的实现,因为 bA 引用?还是应该调用B 的实现,因为bB 对象?

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


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

        【讨论】:

        • 我的问题是为什么静态变量不会发生这种情况?即静态变量可以在不使用静态变量的情况下被覆盖(阴影)。
        • 阅读我的最后两句话。无论变量是否为静态,它们都适用
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-18
        • 2011-09-16
        相关资源
        最近更新 更多