今天我深究了一下java的方法覆盖的语法规则,写了三个类.总共代码行数50行左右.其中的具体类没有实现父类的抽象方法就编译通过了。为了验证我写了测试程序,结果抛出java.lang.AbstractMethodError错误。这说明确实没有实现抽象方法,但是编译没有错误.也没有使用外部jar包,所以不存在jar包冲突问题,也没有怎么利用javaAPI,不存在java版本冲突问题.大家猜猜我是怎么写的?过几天我公布答案

解决方案 »

  1.   

    public class AbstractMethodError extends IncompatibleClassChangeError当应用程序试图调用一个抽象方法时,抛出此错误。通常由编译器捕获此错误;如果某个类的定义自当前执行方法最后一次编译以后作了不兼容的更改,则此错误只可能在运行时发生。
      

  2.   

    就像火龙果说的,编译之后再修改类就只能在运行时抛出该异常了Thrown when an application tries to call an abstract method. Normally, this error is caught by the compiler; this error can only occur at run time if the definition of some class has incompatibly changed since the currently executing method was last compiled.
      

  3.   

    是啊,除了这种方法之外,如果一个未实现抽象方法的类能通过编译的话,那 javac 这个编译器也做得太差了,大家也没必要再继续使用 Java 了,呵呵
      

  4.   

    我说一下结果:
    按照我的步骤做:1建立两个包pack1和pack22在pack1包下建立类A
    代码:
    package pack1;public abstract class A {
    abstract void set();
    }3在pack2包下建立类B
    代码:
    package pack1;public abstract class A {
    abstract void set();
    }4在pack1包下建立类C
    代码
    package pack1;import pack2.B;public class C extends B {
    public static void main(String[] args) {
              A  the=new C();
              the.set();
    }
    }5运行类C中的测试代码
    你们试一试也许是我的编译器的问题
      

  5.   

    对不起类B的代码是:
    package pack2;import pack1.A;public abstract class B extends A { protected String set() {
    return null;
    }}
      

  6.   

    我说一下结果:
    按照我的步骤做:1建立两个包pack1和pack22在pack1包下建立类A
    代码:
    package pack1;public abstract class A {
    abstract void set();
    }3在pack2包下建立类B
    代码:
    package   pack2; import   pack1.A; public   abstract   class   B   extends   A   { protected   String   set()   { 
    return   null; 
    } } 4在pack1包下建立类C
    代码
    package pack1;import pack2.B;public class C extends B {
    public static void main(String[] args) {
      A the=new C();
      the.set();
    }
    }5运行类C中的测试代码
    你们试一试也许是我的编译器的问题
      

  7.   

    真的没问题。好玩。A类定义的方法是package可视的,B类虽然继承了A类,但并没有能覆盖set方法(因为B看不到A的set方法),而是实现了自己的一个set方法。
    到C类继承B类的时候,自然将B类上定义的方法继承过来了(因为B的set方法是protected可视的)。竟然骗过了编译器。
    但执行的时候到底发现有问题了,来自于B的这个set方法不是A的set方法,遂抛异常。LZ怎么发现的?
      

  8.   

    首先声明一下:我做这个的时候是用eclipse做的,有的人说用命令行编译不通过,我试了好像确实是这样.难道是eclipse的bug?
    当时我想这个问题的时候.是从代码覆盖时权限角度出发考虑的.当时说private方法不能被继承和覆盖,我想是和权限有关.我想如果一个父类的方法子类如果没有权限访问,那么能否覆盖?如果覆盖了是不是破坏了封装性.经过尝试发现子类如果无法访问父类方法则不能覆盖,而且可以定义,并且不受影响,只是运行时不能覆盖父类方法,这样在继承链中就会有两个不同版本的方法描述.那么子类编译根据那个运行,我以为会因为矛盾编译不过,但是测试结果却是这样顺便说一下:我也不是为了吊大家的胃口,而是我这个代码是在公司的电脑上做的,公司不让拷贝代码.既公司内部网络与外界隔离.无法及时上传代码.而我发帖是利用公司的公共电脑发的,那个电脑上没有eclipse和jdk,公司估计也不让装,所以无法重现代码.后来的代码是我在家里做的
      

  9.   

    这个真的很牛啊! 以前没碰到过。 实际上没覆盖, 但编译器会认为是覆盖了, 因此没报错。 貌似编译器仅仅是以方法签名来判断是否覆盖的,访问控制符因素根本 没入其法眼,但java doc关羽这个AbstractMethodError的解释又那么言之凿凿,如果java doc是标准的话,那么是编译器实现的问题了!? 看看是不是这样
      

  10.   

    弱弱的问下!   你们说the这个指针指向的是谁!
      

  11.   

    估计与jdk实现有关吧。
    编译器存在bug也不稀奇
      

  12.   

    使用 eclipse 是编译不通过的。
      

  13.   

    我使用的是eclipse编译通过.我还发现eclipse编译错误居然生成错误的class文件.
    顺便说一下CSDN论坛有时登陆之后没反应但是已经登陆,重新刷新页面即可。软件真的经常迷惑人
      

  14.   

    我javac时就出错了:
    B 中的 set() 无法覆盖 A 中的 set();正在尝试使用不兼容的返回类型
      

  15.   

    是什么版本的javac?
    我用的编译通过的是1.6.0_23