为什么当我尝试拥有两个方法名称和参数类型相同的方法时,会出现编译错误?

5
如果我把byte改成int,就会出现编译错误。你能解释一下问题吗?
public class A {
   protected int xy(int x) { return 0; }
}

class B extends A {
   protected long xy(int x) { return 0; } //this gives compilor error
   //protected long xy(byte x) { return 0; } // this works fine
}   

2
因为A.xy的方法签名与B.xy相同:名称相同,参数数量相同且参数类型相同。 - Jeroen Vannevel
你在文本中发布的方法是完全正确的,因为它们具有不同的参数类型。intbyte并不相同。 - Germann Arlington
@GermannArlington:如果你只看标题和代码,可能会有点困惑,但是问题的开头一句话很清楚:“如果我将字节更改为整数,就会出现编译器错误。” - T.J. Crowder
7个回答

6
如果我把byte改成int,我会得到编译错误。
如果你这样做,你就会得到这个:
public class A {
   protected int xy(int x) { return 0; }
}

class B extends A {
   protected long xy(int x) { return 0; }
}   

...而xy方法之间唯一的区别就是它们的返回类型。方法不能仅通过它们的返回类型来区分,这是Java定义的方式。请考虑以下内容:

myInstance.xy(1);

应该调用哪个xy函数?long xy(int x)还是int xy(int x)

如果你的目标是在B覆盖A#xy,那么你需要将其返回类型设置为int以匹配A#xy


2

在同一继承树中的不同类中分别放置方法,即使这些方法具有相同的签名,也不能在类中拥有两个这样的方法。即基类和子类。

注意:仅通过返回类型无法使编译器理解方法之间的区别。返回类型也不包含在方法签名中。


2

您正在尝试编写两个具有相同名称和输入参数的方法,这是不可能的。

请看以下两个方法:

float met(){
  return 4.5;
}

double met(){
  return 5.4;
}

如果我们写下这行代码

int x = (int)met();

什么方法会被调用?

无法决定,因此不允许出现这种情况。


1
那是因为如果您将byte更改为int,则基类和子类中会具有相同签名的方法(相同的方法名称和参数类型),因此返回类型也应该相同。因为不是(int和long),所以这会导致错误。

1
你可以仅通过参数和名称来区分方法。
     both methods are in same class B

     b.xy(byte x) or b.xy(int x) is called for input xy(0) or xy(1)

1
覆盖方法应该返回一个类型,该类型可以替换被覆盖方法返回的类型。

0

因为当你将 byte 改成 int 时,调用该方法的实例不知道指的是哪个方法。被覆盖的方法还是旧的方法?

这就是为什么不允许有相同的签名(方法名称、参数类型和数量)。只是提供一些信息:返回类型不是签名的一部分。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接