根据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具有相同的参数类型:
- 它们具有相同数量的形式参数(可能为零)
- 它们具有相同数量的类型参数(可能为零)
- 设A1,...,An是M的类型参数,B1,...,Bn是N的类型参数。将N中每个Bi的出现重命名为Ai后,对应类型变量的边界相同,并且M和N的形式参数类型相同。
...
如果m1是m2的子签名或m2是m1的子签名,则两个方法签名m1和m2是覆盖等效的。
形式参数通过列表指定,因此,“M和N的形式参数类型相同”,它们必须是相同的列表,并且列表有序。
由于3中的对应关系依赖于顺序,因此类型参数的顺序也很重要。
当您处理字节码/JNI约定的方法描述符时,这变得更加明显。
MethodDescriptor: ( ParameterDescriptor* ) ReturnDescriptor
顺序必须相同,否则不会发生覆盖。
不,顺序很重要!
Java中覆盖方法的规则
规则1)如果一个类继承另一个类并定义了与名称和参数列表相同的方法,则该方法被称为被覆盖的方法。
规则2)基类中定义的方法应在派生类中可见。如果不是这样,派生类中的方法将不被视为覆盖版本,而将被视为普通方法。
规则3)覆盖和被覆盖方法的方法名称和参数列表应相同。但返回类型可以是协变的。这意味着,如果超类中的方法的返回类型是Map,则相同方法的返回类型可以是HashMap。
规则4)覆盖方法(在派生类中)中的访问限定符不应比被覆盖方法(在基类中)更加限制。这意味着,如果基类方法的访问限定符为protected,则派生类方法的访问限定符不应为默认或私有,但可以是protected、public。各种限定符的可见度逐渐增加的顺序是:
private、default、protected、public
规则5)派生类方法中指定的异常应该与它们相同或是子类。因此,如果基类方法在throws子句中指定了IOException异常,则派生类方法可以指定FileNotFoundException、IOException异常,但不能指定Exception异常。
public void foo(int x, Object y)
不能被以下方法覆盖:
public void foo(Object y, int x)