我们知道方法签名只包含方法名称和参数列表,但不包括方法返回类型。那么为什么我为以下代码收到编译器错误,因为java没有区分具有相同签名的方法。
public class InterfaceTest implements I2{
public void hello(){ }
public void world(){ }
}
interface I1{
public int hello();
}
interface I2 extends I1{
public void world();
}
答案 0 :(得分:4)
你这里没有overloading
,你是overriding
和hidding
方法,但没有正确的方法......有两种可能来解决你的问题:
public class InterfaceTest implements I2{
public void hello(int a){ } // overloaded method
@Override
public int hello(){ return 1; } // overriden method
public void world(){ } // this hides I1 method
}
如果你在一个班级中尝试这个,那就是:
public void hello() {}
public int hello() {return 1;}
您将收到Duplicate method hello() in type YourClass
错误,因为要overloading
方法,您必须更改签名的FormalParameterListopt
:
如果一个类[...]的两个方法具有相同的名称但签名不是覆盖等效,则方法名称被称为重载
方法签名仅包括方法名称和参数列表,但不包括方法返回类型
根据JSL §8.4,当您声明方法时:
MethodDeclaration:
MethodHeader MethodBody
MethodHeader:
MethodModifiersopt TypeParametersopt Result MethodDeclarator Throwsopt
MethodDeclarator:
Identifier ( FormalParameterListopt )
所以当你这样做时:
public int hellow(int number) throws Exception;
//| | | | └ throwing an exception (Throwsopt)
//| | | └──────────── receiving one int argument (MethodDeclarator FormalParameterListopt )
//| | └─────────────────── name hellow (MethodDeclarator Identifier)
//| └─────────────────────── returning an int (Result)
//└────────────────────────────── is a public method (MethodModifiersopt)
答案 1 :(得分:2)
您在此处引用方法overriding
而不是overloading
。返回类型必须与超类/接口中原始重写方法中声明的返回类型相同或者是子类型。
答案 2 :(得分:1)
根据this article,返回类型是声明的一部分。并且声明必须在实现类中相同。此外,扩展接口继承了parent-interface中的所有方法,因此hellow-method必须与i1的hellow-method匹配
答案 3 :(得分:1)
问题正是因为java 不能区分具有相同签名(但返回类型不同)的方法。
让我们看看你的情况会发生什么(假设有可能),
您可以执行以下操作,
InterfaceTest obj = new InterfaceTest();
obj.hellow(); // The compiler knows it returns void here.
i1 obj1 = new InterfaceTest();
obj1.hellow(); // The compiler thinks it return an int, when it doesn't return anything.
答案 4 :(得分:1)
方法的返回类型是其签名的一部分,您的编译错误是因为您的返回类型与您在脸部中声明的类型不匹配。
答案 5 :(得分:1)
您正在实现类中的接口,该接口与接口“hello()”具有相同的方法名称,因此有两种情况
1)如果您正在实现一个接口,您应该在这种情况下编写其方法的具体实现
但您只提供了一种方法的实现
“public void world()”
所以它会要求你实现另一个方法,它将成为这个类的一部分。
2)当你提供public void world()方法的具体实现时,它会与你的方法 public void hello()发生碰撞,现在当被覆盖的方法成为你的类的成员时你的方法有相同的参数列表,所以它将失败超载条件。
因此,这将使覆盖和重载功能都失败。