为什么我到这里方法覆盖错误?

时间:2013-07-07 11:19:24

标签: java compiler-errors method-hiding

这是我的超类:

class Superclass {

       int a=89;

       final  static void m( int p){
            System.out.println("Inside superclass");
       }   

       static void n(){
            system.out.print("superclass");
       }

}

这是我的子类::

 class Subclass extends Superclass {

        int a=90;

        static  void m( int p){
             System.out.println("Inside subclass");
        }

        static void n(){
             system.out.print("subclass");  
        }
  }

主要课程:

   class main {
        public  static void main(String[] args) {
            Subclass.m(89);
           new Subclass().n();
        }
   }

问题在于我无法理解为什么Javac在静态方法中给我压倒一切的错误。所以P.S plzz详细说明所有覆盖规则对于隐藏也是有效的。像

  

新方法定义必须具有相同的方法签名(即,   方法名称和参数)和相同的返回类型。是否   重写方法中的参数应该是最终的   子类方法的签名的自由裁量权不包括   参数的最终修饰符,只有它们的类型和顺序。

  

方法定义不能缩小方法的可访问性,但是   它可以加宽它新的方法定义只能指定全部或   none,或异常类的子集(包括它们的   子类)在重写方法的throws子句中指定   超类

我的错误是: 运行:

  

线程“main”中的异常java.lang.RuntimeException:Uncompilable   源代码 - javaapplication3.Subclass中的m(int)无法覆盖   javaapplication3.Superclass中的m(int)重写方法是   static,final at javaapplication3.Subclass.m(JavaApplication3.java:18)     在javaapplication3.min.main(JavaApplication3.java:25)Java结果:1

我还想问一下,当子类隐藏方法被超类扩展时,是否会从classname调用静态成员来解析方法的版本 如果我创建匿名对象然后调用方法然后编译器如何确定应该调用哪个版本的方法。 在主类的上面代码中我输入:new Subclass()。n();

即使我没有提供引用变量的类型,编译器如何知道方法的子类版本应该被调用

2 个答案:

答案 0 :(得分:4)

来自JLS 8.4.3.3

  

可以将方法声明为final,以防止子类覆盖或隐藏它。

当从子类的实例调用时,具有来自父类的相同签名的静态方法是hidden。但是,您无法覆盖/隐藏final methods。 关键字final将禁止隐藏该方法。因此它们无法隐藏,尝试这样做会导致编译器错误。 Javaranch上有一个很好的解释。

答案 1 :(得分:2)

您在此观察的内容符合JLS 8.4.3.3的规定:

  

尝试覆盖或隐藏最终结果是编译时错误   方法

您正在尝试覆盖子类中的final static void m方法,这是Java编译器不允许的。