问题在于其 父类的方法 seta(int a) 的方法体内有 this.i=a; 用到了private变量i,而
private变量是不允许被继承的,所以你必须重载seta(int a),如果父类中的i不是private的,则不会出问题

解决方案 »

  1.   

    子类只能override父类的方法,而不能overload父类的方法
      

  2.   

    class A {
    private int i;
    public void seta(int a){
    this.i=a;
    }
    public int geta(){
    return this.i;
    }
    }public class B extends A{

    //没有这句的话就会抱错。
    //public void seta(int a){}
    ///////

    public void seta(float a){
    super.seta((int)a);
    }
    public static void main(String args[]){
    B b1=new B();
    b1.seta(11);//出错
    }
    }保存为B.java,我运行了,没错
      

  3.   

    to yoken, 你用的是什么jdk? 用1.4.2是会报错的.
      

  4.   

    to kinzey34:我即使把a改成public的,也是会出错。
    to grgh2000:那为什么c++不会出错?
      

  5.   

    to newwaylw(勇敢去爱):
    yoken(雨泉)将楼主的程序稍作修改,将class B设为public
    并存放于B.javajdk1.4.2下测试无误
    这个东东应该跟版本无关吧? ^_^
      

  6.   

    to shattttt(shattttt):
    你的程序存放在什么文件中?
      

  7.   

    to grgh2000(太阳):
    子类只能override父类的方法,而不能overload父类的方法
    这话不对
      

  8.   

    to danceflash:程序放在A.java文件中。
      

  9.   

    赫赫,搂主为什么老想用c++来比较?两种语言虽然都自称是oo,但是具体实现还是很不同的阿
      

  10.   

    to danceflash:没有抱错?不可能吧?我这里显示的错误是:B.java:14: reference to seta is ambiguous, both method seta(int) in A and metho
     seta(float) in B match
                    b1.seta(11);
                      ^
    1 errorto fredliu:因为我想搞明白不同在哪里?而且我的想法很简单,我不过就是想重载,为什么不行?难道我非得复写seta(int a)?那样子的话我还要继承做什么?
      

  11.   

    这个应该是说
    它不知道该调用哪个函数
    编译器认为seta(11)即可以调用seta(int)又可以调用seta(float)
    好奇怪的报错啊,我这里确实没有 -_-b
      

  12.   

    to mymoto(忽忽):
    你也报错了? ^_^
      

  13.   

    to danceflash:你用的是哪个版本的编译器?
      

  14.   

    b1.seta(11L); 等价与 b1.seta((float)11);
    不会出错。
    但是
    int s = 11;
    b1.seta(s);
    还是同样的错误。
      

  15.   

    我的搞定了 看下面的代码:
    class A {
    private int i;
    public void seta(int a){
    this.i=a;
    }
    public int geta(){
    return this.i;
    }
    }public class B extends A{
    public void seta(float a){
    super.seta((int)a);
    System.out.println ("float a = " + a);
    }
    public static void main(String args[]){
    float a = 11;
    B b1=new B();
    b1.seta(a);
    }
    }
      

  16.   

    不是你的类有问题,而是你的调用有问题,
    当你传递参数11的时候,seta(int)和seta(float)都能接受,
    产生调用的二义性,相信C++中也不可以
      

  17.   

    to shattttt (shattttt) 
    你这样不是重载
    只是定义了一个新的方法,
    你的参数对两个方法都可以,使编译器无法确定使用子类的方法,还是使用继承来的方法
    seta(11f);//调用seta(float)如果你要重载
    应该保持方法名称不变,参数类型、个数不变class B extends A
    {
      public void seta(int a)
      {
        //do something
       }
    }
      

  18.   

    to: danceflash(Wine)
    我的也报错,如果按楼主那么些,谁的都报错
      

  19.   

    to  ustbzhangwei(wei) :
    为什么重载必须要保持参数类型和个数不变,保持参数类型和个数不变的话拿不叫重载,比如
    你定义
    public void seta(int a){}
    public void seta(int a){}
    这样的代码能通过吗,当然要函数名不变,而参数类型或者参数个数变化才叫重载象你上面说得我也不太明白
    比如如果我在B里面再复写继承来的public void seta(int a),那么整个程序就可以运行,编译器就可以确定是用哪个方法,而直接继承过来的seta(int a)如果不复写就会出错,这是为什么
      

  20.   

    to web_spider(蓦然回首,那人却在、灯火阑珊处。) :
    它传入的是int型,编译器当然要默认优先选择是用seta(int a)来进行处理了,怎么会无法分辨呢?
      

  21.   

    我昨天在家里的那台机器上不报错,用的时jdk1.4.2
    我今天换了台机器,用的是jdk1.4.1,报错
    莫非在1.4.1以及以前版本中,对基本类型的检查有问题?
      

  22.   

    to ustbzhangwei(wei):
    应该保持方法名称不变,参数类型、个数不变这个是重写(overriding)
    重载是overload
      

  23.   

    to mymoto(忽忽):
    它传入的是int型,编译器当然要默认优先选择是用seta(int a)来进行处理了,怎么会无法分辨呢?我也是这么认为的,可是现在的报错就是说它认为两个都可以调用
    有点儿晕了,以前也在C++的教程中看到过类似的例子,不过有点儿忘了
    到底是怎么回事儿呢?
      

  24.   

    class A {
    private int i;
    public void seta(int a){
    this.i=a;
    }
    public int geta(){
    return this.i;
    }
    }public class B extends A{

    //没有这句的话就会抱错。
    //public void seta(int a){}
    ///////

    public void seta(float a){
    super.seta((int)a);
    }
    public static void main(String args[]){
    B b1=new B();
    b1.seta(11F);//---------------错误排除
    }
    }原因,方法的二义性导致出错
    这只能说明java比c++严格。
      

  25.   

    理论上将传入的为int型就应该调用seta(int),
    但setb(long)也同样能接受int型参数。
    这样两个函数都能满足被调用的条件,
    编译器就傻了,不知道用那一个好了,
    于是就出现方法调用的二义性。
    我是从C++过来的,相信,好的C++编译器也不会让通过的。
    qlampskyface(天空的样子)的方法是个好办法。
      

  26.   

    class A {
    private int i;
    public void seta(int a){
    this.i=a;
    System.out.println("*******************************");
    }
    public int geta(){
    return this.i;
    }
    }public class B extends A{

    public static void main(String args[]){
    B b1=new B();
    b1.seta(11);//出错
    }
    /*public void seta(float a){
    super.seta((int)a);
    }*/
    }说明子类直接调用父类方法,且float和int之间有默认转换的关系,所以,也就产生了上述二义性问题,如将float a换成String a即没有这种问题
      

  27.   

    我认为
    编译器在寻找函数时,先找该类自己的函数,然后才是从父类继承来的函数
    int 可以自动转换成float,所以编译器找到了两个函数可以匹配,就报错了
      

  28.   

    搂住。我测试过了,你的原来的代码没有问题(jdk1.4.2_02)
    java会根据方法调用的参数类型自动匹配相关的方法。这个没有问题。不知道你是用的什么编译器?
      

  29.   

    不能通过(JBuilderX+jdk1.4),错误提示:
    "B.java": reference to seta is ambiguous; both method seta(int) in A and method seta(float) in B match at line 16, column 20
      

  30.   

    public class A {
    private int i;
    public void seta(int a){
    this.i=a;
    }
    public int geta(){
    return this.i;
    }
    }class B extends A{

    //没有这句的话就会抱错。
    //public void seta(int a){}
    ///////

    public void seta(float a){
    super.seta((int)a);
    }
    public static void main(String args[]){
    B b1=new B();
    b1.seta((float)11);//==========================没有出错
    }
    }
    注意:加了一个float()就不会报错了(因为11,在java里默认的是int型),此时调用的B的seta(float a)方法了,这个问题应该是方法调用不明确造成的。
      

  31.   

    B继承A的时候并没有继承private i在b1.seta(11)的时候调用的是父类继承过来的方法:
    public void seta(int a){
    this.i=a;//注意这里!!由于B类并没有继承到i,所以会出错!!!
                  }
      

  32.   

    我在JDK 1.4.1下编译也报错。既然有些朋友已经在jdk1.4.2下通过,我想应该属于jdk版本的问题吧。但是有一点可以肯定,当去掉//public void seta(int a){}的注释后就可以编译通过,说明在这样的情况下(同名方法写在一个类中) "java会根据方法调用的参数类型自动匹配相关的方法"。可是却不能在父类的seta(int a)与子类中的seta(float a)作出判断,实在难于理解。我想目前要么就在调用时显示转换吧,要么就升级JDK吧。
      

  33.   

    刚刚又去搜了下sun公司的bug database,有一个BUG报告正好是说这个问题,一模一样。贴出来大家参考一下:
    Bug Id  4038412
     
    Votes  0
     
    Synopsis  Compiler improperly reports ambiguous method
     
    Category  java:compiler
     
    Reported Against  1.1, 1.2alpha
     
    Release Fixed   
     
    State  Closed, not a bug
     
    Related Bugs  4067106
     
    Submit Date  Mar 12, 1997 
     
    Description  <p>This is not a bug.<p>The following code reports that the reference to method1 is ambiguous:
    <code><pre>
    class A
    {
       public void method1( int x )
       {  System.out.println( "A.method1 (int) : " + x );
       }   public static void main( String[] xArgs )
       {  ASub a1 = new ASub();
          a1.method1( 3 );
       }
    }--------------class ASub extends A
    {
       public void method1( long x )
       {  System.out.println( "ASub.method1 (long) : " + x );
       }
    }
    <\pre><\code>
    <p>When determining if there is a maximally specific method, the compiler uses
    not only the types of the arguments, but also the type of the <em>definer<\em>.
     In the example above, the versions of method1 defined in ASub and A are both
    maximally specific: A's method1 is not more specific than ASub's because it's
    the class A cannot be converted to the class ASub by method invocation
    conversion.  ASub's method1 is not more specific than A's because the type long
    cannot be converted to int by method invocation conversion.  Since there is
    more than one maximally specific method, we have an ambiguity.<p>The relevant section of the JSL is 15.11.2.2.  Please note the line
    <ul>
    <li> T can be converted to U by method invocation conversion.
    <\ul>
    --------------------------------------------------------------------------------class A
    {
       public void method1( int x )
       {  System.out.println( "A.method1 (int) : " + x );
       }   public static void main( String[] xArgs )
       {  ASub a1 = new ASub();
          a1.method1( 3 );
       }
    }--------------class ASub extends A
    {
       public void method1( long x )
       {  System.out.println( "ASub.method1 (long) : " + x );
       }
    }--------------Compiler produces error "Reference to method1 is ambiguous" when
    compiling class A.  According to section 15.11.2.2 of the
    Language Specification the "most specific" method should be
    chosen.  Since, by method invocation conversion, an "int"
    argument can be converted to a "long" but a "long" cannot be
    converted to an "int", the method (in class A) with the "int"
    argument should be "more specific" and method1 should not be
    ambiguous.
     
    Workaround  
     
    Evaluation  <p>This is not a bug.<p>The following code reports that the reference to method1 is ambiguous:
    <code><pre>
    class A
    {
       public void method1( int x )
       {  System.out.println( "A.method1 (int) : " + x );
       }   public static void main( String[] xArgs )
       {  ASub a1 = new ASub();
          a1.method1( 3 );
       }
    }--------------class ASub extends A
    {
       public void method1( long x )
       {  System.out.println( "ASub.method1 (long) : " + x );
       }
    }
    <\pre><\code>
    <p>When determining if there is a maximally specific method, the compiler uses
    not only the types of the arguments, but also the type of the <em>definer<\em>.
     In the example above, the versions of method1 defined in ASub and A are both
    maximally specific: A's method1 is not more specific than ASub's because it's
    the class A cannot be converted to the class ASub by method invocation
    conversion.  ASub's method1 is not more specific than A's because the type long
    cannot be converted to int by method invocation conversion.  Since there is
    more than one maximally specific method, we have an ambiguity.<p>The relevant section of the JSL is 15.11.2.2.  Please note the line
    <ul>
    <li> T can be converted to U by method invocation conversion.
    <\ul>xxxxx@xxxxx 1997-09-03 
       THU MAY 13 07:18 P.M. 1999
    bhudson
    An easy but messy work-around is to declare 
    ASub.method1(int)
    I would argue that while the JLS does indeed
    make for this reading, the intuitive reading
    makes at least as much sense (in other words,
    that the JLS should be amended in this respect).
    So this may not be a bug, but it is an ease-of-
    use issue.
    The informal intuition is that a subclass or
    subinterface has all the methods specifically
    declared in its source file, plus all those 
    declared in its superclass and superinterfaces.
    Therefore, the call is not ambiguous: ASub
    has both methods
    void method1(int)
    void method1(long)
    because it inherits the former.  With this flat
    set of methods, we use the normal resolution
    for overloaded methods seen in 15.11.2.3,
    yielding the expected method call. 
    按照SUN的说法,这个问题确实存在,但不是个BUG,而是参照JSL is 15.11.2.2的前提下,编译器确实无法确定哪个方法更适合(more specific)。所以我正在下载jdk1.4.2,下完了测试下,看看是不是真的已经没有这个问题了。待会来看。
      

  34.   

    看了前面的帖子,真是令人汗~~~~
    一个文件最多只能有一个public类,而且如果有的话一定是带有main函数的那个类你把public给类B不就没问题了,搂住多看一些java的基础,不要动不动就说java的bug,你可知道java有几年的历史?多少人的结晶?就这么轻易让你发现bug
      

  35.   

    刚刚装了jdk1.4.2,确实可以编译通过。简单点,升级JDK吧。
      

  36.   

    moke33(勤奋的菜鸟),    我测试过,就算将两个类分开写成两个JAVA文件,这个问题在JDK1.4.1下仍然存在。所以楼主轻言这是BUG,虽然有点草率,但显然你也没有对自己的建议进行最起码的测试  ----“你把public给类B不就没问题了”,你试过了吗?
      

  37.   

    也许他用的是jdk1.4.2 ^_^这确实是jdk编译器的区别
    昨天刚看到这个问题的时候
    我在我的环境下测试都是通过的
    结果今天换了台机器,在jdk1.4.1环境下测才知道楼主看到的报错 ^_^
      

  38.   

    我试了一下
    编译报错为该函数不知道用哪个对应.
    改为
    b1.seta((float)11);就可以了
      

  39.   

    原来如此,谢谢 allof01(我行我素)
    谢谢大家。