5

根据 javadoc

子类中具有相同签名(名称,加上其参数的编号和类型)和返回类型作为超类中的实例方法的实例方法会覆盖超类的方法。

我的问题是 - 参数的顺序无关紧要吗?如果它们具有相同的名称并且它们也是相同的类型?

4

7 回答 7

6

顺序很重要,因此具有不同顺序的相同参数的两个方法不被认为具有相同的签名。
例如,此示例无法编译:

interface Foo {
    void doIt(String what, int times);
}

class Bar implements Foo {
    public void doIt(int times, String what) {}
}

然而,参数的名称是无关紧要的。这很好:

interface Foo {
    void doIt(String what, int times);
}

class Bar implements Foo {
    public void doIt(String andNowForSomeThingCompetelyDifferent, int theLarch) {}
}
于 2013-04-23T19:05:17.790 回答
2

Java 语言规范说顺序很重要,但需要一些梳理才能解释原因:

8.4.1. 形式参数

方法或构造函数的形式参数(如果有)由逗号分隔的参数说明符列表指定。

...

8.4.2. 方法签名

如果满足以下所有条件,则两个方法或构造函数声明 M 和 N 具有相同的参数类型:

  1. 它们具有相同数量的形式参数(可能为零)
  2. 它们具有相同数量的类型参数(可能为零)
  3. 令 A 1 , ..., A n为 M 的类型参数,令 B 1 , ..., B n为 N 的类型参数。将 N 的类型中出现的每个 B i重命名为 A i后,对应类型变量的边界相同,M和N的形参类型相同。

...

如果 m1 是 m2 的子签名或 m2 是 m1 的子签名,则两个方法签名 m1 和 m2 是覆盖等效的。

形参被指定为一个列表,因此“M和N的形参类型”要相同,它们必须是相同的列表,并且列表是顺序相关的。

由于 3 中的对应关系依赖于顺序,因此类型参数的顺序也很重要。

当您处理Method Descriptors的字节码/JNI 约定时,这一点变得更加明显。

MethodDescriptor:
    ( ParameterDescriptor* ) ReturnDescriptor
于 2013-04-23T19:07:16.987 回答
1

顺序也必须相同,否则不会发生覆盖

于 2013-04-23T19:06:26.293 回答
1

不,顺序很重要!

Java 中重写方法的规则

规则 1) 如果扩展另一个类的类定义了具有相同名称和参数列表的方法,则称该方法被覆盖。

规则 2) 基类中定义的方法在派生类中应该是可见的。如果不是这样,派生类中的方法将不会被视为重写版本,而是将被视为普通方法。

规则 3) 方法名称和参数列表对于覆盖和被覆盖的方法应该是相同的。但是返回类型可以是协变的。这意味着如果超类中方法的返回类型是Map,那么同一个方法的返回类型可以是HashMap。

规则 4)覆盖方法(在派生类中)的访问说明符不应比覆盖方法(在基类中)的访问说明符更具限制性。这意味着如果基类方法的访问说明符受到保护,那么派生类方法的访问说明符不应是默认或私有的,但可以是受保护的、公共的。各种说明符的可见性增加的顺序是:

私有的、默认的、受保护的、公共的

规则 5) 派生类方法中指定的异常应该是相同的或者是它们的子类。因此,如果基类方法在 throws 子句中将异常指定为 IOException,则派生类方法可以将异常指定为 FileNotFoundException、IOException 但不是 Exception。

于 2013-04-23T19:08:22.343 回答
0

顺序很重要。如果订单不同,则签名不同。 public void foo(int x, Object y) 不能被覆盖 public void foo(Object y, int x)

于 2013-04-23T19:06:09.807 回答
0

如果顺序不同,编译器将无法找到该方法,并且您将收到一条错误消息

于 2013-04-23T19:09:45.447 回答
0

请注意,当您使用多个参数时,方法调用必须具有与参数数量相同的参数,并且参数必须以相同的顺序传递。

来源:https://www.w3schools.com/java/java_methods_param.asp

于 2020-06-28T10:45:19.640 回答