根据 javadoc
子类中具有相同签名(名称,加上其参数的编号和类型)和返回类型作为超类中的实例方法的实例方法会覆盖超类的方法。
我的问题是 - 参数的顺序无关紧要吗?如果它们具有相同的名称并且它们也是相同的类型?
根据 javadoc
子类中具有相同签名(名称,加上其参数的编号和类型)和返回类型作为超类中的实例方法的实例方法会覆盖超类的方法。
我的问题是 - 参数的顺序无关紧要吗?如果它们具有相同的名称并且它们也是相同的类型?
顺序很重要,因此具有不同顺序的相同参数的两个方法不被认为具有相同的签名。
例如,此示例无法编译:
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) {}
}
Java 语言规范说顺序很重要,但需要一些梳理才能解释原因:
8.4.1. 形式参数
方法或构造函数的形式参数(如果有)由逗号分隔的参数说明符列表指定。
...
8.4.2. 方法签名
如果满足以下所有条件,则两个方法或构造函数声明 M 和 N 具有相同的参数类型:
- 它们具有相同数量的形式参数(可能为零)
- 它们具有相同数量的类型参数(可能为零)
- 令 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
顺序也必须相同,否则不会发生覆盖
不,顺序很重要!
Java 中重写方法的规则
规则 1) 如果扩展另一个类的类定义了具有相同名称和参数列表的方法,则称该方法被覆盖。
规则 2) 基类中定义的方法在派生类中应该是可见的。如果不是这样,派生类中的方法将不会被视为重写版本,而是将被视为普通方法。
规则 3) 方法名称和参数列表对于覆盖和被覆盖的方法应该是相同的。但是返回类型可以是协变的。这意味着如果超类中方法的返回类型是Map,那么同一个方法的返回类型可以是HashMap。
规则 4)覆盖方法(在派生类中)的访问说明符不应比覆盖方法(在基类中)的访问说明符更具限制性。这意味着如果基类方法的访问说明符受到保护,那么派生类方法的访问说明符不应是默认或私有的,但可以是受保护的、公共的。各种说明符的可见性增加的顺序是:
私有的、默认的、受保护的、公共的
规则 5) 派生类方法中指定的异常应该是相同的或者是它们的子类。因此,如果基类方法在 throws 子句中将异常指定为 IOException,则派生类方法可以将异常指定为 FileNotFoundException、IOException 但不是 Exception。
顺序很重要。如果订单不同,则签名不同。
public void foo(int x, Object y)
不能被覆盖
public void foo(Object y, int x)
如果顺序不同,编译器将无法找到该方法,并且您将收到一条错误消息
请注意,当您使用多个参数时,方法调用必须具有与参数数量相同的参数,并且参数必须以相同的顺序传递。
来源:https://www.w3schools.com/java/java_methods_param.asp