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,我运行了,没错
to yoken, 你用的是什么jdk? 用1.4.2是会报错的.
to kinzey34:我即使把a改成public的,也是会出错。 to grgh2000:那为什么c++不会出错?
to newwaylw(勇敢去爱): yoken(雨泉)将楼主的程序稍作修改,将class B设为public 并存放于B.javajdk1.4.2下测试无误 这个东东应该跟版本无关吧? ^_^
to shattttt(shattttt): 你的程序存放在什么文件中?
to grgh2000(太阳): 子类只能override父类的方法,而不能overload父类的方法 这话不对
to danceflash:程序放在A.java文件中。
赫赫,搂主为什么老想用c++来比较?两种语言虽然都自称是oo,但是具体实现还是很不同的阿
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)?那样子的话我还要继承做什么?
b1.seta(11L); 等价与 b1.seta((float)11); 不会出错。 但是 int s = 11; b1.seta(s); 还是同样的错误。
我的搞定了 看下面的代码: 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); } }
to shattttt (shattttt) 你这样不是重载 只是定义了一个新的方法, 你的参数对两个方法都可以,使编译器无法确定使用子类的方法,还是使用继承来的方法 seta(11f);//调用seta(float)如果你要重载 应该保持方法名称不变,参数类型、个数不变class B extends A { public void seta(int a) { //do something } }
to: danceflash(Wine) 我的也报错,如果按楼主那么些,谁的都报错
to ustbzhangwei(wei) : 为什么重载必须要保持参数类型和个数不变,保持参数类型和个数不变的话拿不叫重载,比如 你定义 public void seta(int a){} public void seta(int a){} 这样的代码能通过吗,当然要函数名不变,而参数类型或者参数个数变化才叫重载象你上面说得我也不太明白 比如如果我在B里面再复写继承来的public void seta(int a),那么整个程序就可以运行,编译器就可以确定是用哪个方法,而直接继承过来的seta(int a)如果不复写就会出错,这是为什么
to web_spider(蓦然回首,那人却在、灯火阑珊处。) : 它传入的是int型,编译器当然要默认优先选择是用seta(int a)来进行处理了,怎么会无法分辨呢?
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即没有这种问题
我认为 编译器在寻找函数时,先找该类自己的函数,然后才是从父类继承来的函数 int 可以自动转换成float,所以编译器找到了两个函数可以匹配,就报错了
不能通过(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
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)方法了,这个问题应该是方法调用不明确造成的。
B继承A的时候并没有继承private i在b1.seta(11)的时候调用的是父类继承过来的方法: public void seta(int a){ this.i=a;//注意这里!!由于B类并没有继承到i,所以会出错!!! }
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,下完了测试下,看看是不是真的已经没有这个问题了。待会来看。
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,我运行了,没错
to grgh2000:那为什么c++不会出错?
yoken(雨泉)将楼主的程序稍作修改,将class B设为public
并存放于B.javajdk1.4.2下测试无误
这个东东应该跟版本无关吧? ^_^
你的程序存放在什么文件中?
子类只能override父类的方法,而不能overload父类的方法
这话不对
seta(float) in B match
b1.seta(11);
^
1 errorto fredliu:因为我想搞明白不同在哪里?而且我的想法很简单,我不过就是想重载,为什么不行?难道我非得复写seta(int a)?那样子的话我还要继承做什么?
它不知道该调用哪个函数
编译器认为seta(11)即可以调用seta(int)又可以调用seta(float)
好奇怪的报错啊,我这里确实没有 -_-b
你也报错了? ^_^
不会出错。
但是
int s = 11;
b1.seta(s);
还是同样的错误。
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);
}
}
当你传递参数11的时候,seta(int)和seta(float)都能接受,
产生调用的二义性,相信C++中也不可以
你这样不是重载
只是定义了一个新的方法,
你的参数对两个方法都可以,使编译器无法确定使用子类的方法,还是使用继承来的方法
seta(11f);//调用seta(float)如果你要重载
应该保持方法名称不变,参数类型、个数不变class B extends A
{
public void seta(int a)
{
//do something
}
}
我的也报错,如果按楼主那么些,谁的都报错
为什么重载必须要保持参数类型和个数不变,保持参数类型和个数不变的话拿不叫重载,比如
你定义
public void seta(int a){}
public void seta(int a){}
这样的代码能通过吗,当然要函数名不变,而参数类型或者参数个数变化才叫重载象你上面说得我也不太明白
比如如果我在B里面再复写继承来的public void seta(int a),那么整个程序就可以运行,编译器就可以确定是用哪个方法,而直接继承过来的seta(int a)如果不复写就会出错,这是为什么
它传入的是int型,编译器当然要默认优先选择是用seta(int a)来进行处理了,怎么会无法分辨呢?
我今天换了台机器,用的是jdk1.4.1,报错
莫非在1.4.1以及以前版本中,对基本类型的检查有问题?
应该保持方法名称不变,参数类型、个数不变这个是重写(overriding)
重载是overload
它传入的是int型,编译器当然要默认优先选择是用seta(int a)来进行处理了,怎么会无法分辨呢?我也是这么认为的,可是现在的报错就是说它认为两个都可以调用
有点儿晕了,以前也在C++的教程中看到过类似的例子,不过有点儿忘了
到底是怎么回事儿呢?
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++严格。
但setb(long)也同样能接受int型参数。
这样两个函数都能满足被调用的条件,
编译器就傻了,不知道用那一个好了,
于是就出现方法调用的二义性。
我是从C++过来的,相信,好的C++编译器也不会让通过的。
qlampskyface(天空的样子)的方法是个好办法。
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即没有这种问题
编译器在寻找函数时,先找该类自己的函数,然后才是从父类继承来的函数
int 可以自动转换成float,所以编译器找到了两个函数可以匹配,就报错了
java会根据方法调用的参数类型自动匹配相关的方法。这个没有问题。不知道你是用的什么编译器?
"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
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)方法了,这个问题应该是方法调用不明确造成的。
public void seta(int a){
this.i=a;//注意这里!!由于B类并没有继承到i,所以会出错!!!
}
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,下完了测试下,看看是不是真的已经没有这个问题了。待会来看。
一个文件最多只能有一个public类,而且如果有的话一定是带有main函数的那个类你把public给类B不就没问题了,搂住多看一些java的基础,不要动不动就说java的bug,你可知道java有几年的历史?多少人的结晶?就这么轻易让你发现bug
昨天刚看到这个问题的时候
我在我的环境下测试都是通过的
结果今天换了台机器,在jdk1.4.1环境下测才知道楼主看到的报错 ^_^
编译报错为该函数不知道用哪个对应.
改为
b1.seta((float)11);就可以了
谢谢大家。