【问题标题】:Java Method Signatures and InterfaceJava 方法签名和接口
【发布时间】:2015-11-06 08:59:12
【问题描述】:

我们知道方法签名仅包括方法名称和参数列表,但不包括方法返回类型。那么为什么我会收到以下代码的编译器错误,因为 java 不区分具有相同签名的方法。

 public class InterfaceTest implements I2{

     public void hello(){  }

     public void world(){  }
}

interface I1{
    public int hello();
}

interface I2 extends I1{
  public void world();
}

【问题讨论】:

  • @Override注释类“InterfaceTest”中的方法world()。但它仍然会声明你必须覆盖int hellow()

标签: java methods interface


【解决方案1】:

您在这里没有overloading,您是overridinghidding 方法,但方法不正确....有两种可能性可以解决您的问题:

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)

【讨论】:

    【解决方案2】:

    您在这里指的是方法overriding,而不是overloading。返回类型必须与超类/接口中原始重写方法中声明的返回类型相同,或者是其子类型。

    【讨论】:

      【解决方案3】:

      根据this article,返回类型是声明的一部分。实现类中的声明必须相同。此外,扩展接口继承父接口的所有方法,因此您的hello-method 必须与i1 中的hello-method 匹配

      【讨论】:

        【解决方案4】:

        问题正是因为 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.
        

        【讨论】:

          【解决方案5】:

          方法的返回类型是其签名的一部分,您的编译错误是因为您的返回类型与接口中声明的类型不匹配。

          【讨论】:

            【解决方案6】:

            你在一个类中实现一个接口,它的方法名与接口“hello()”相同,所以有两种情况

            1) 如果你正在实现一个接口,你应该在这种情况下编写其方法的具体实现

            1. public int hello();
            2. public void world();

            但你只提供了一种方法的实现

            • “公共虚空世界()”

              所以它会要求你实现另一个方法,它将成为这个类的一部分。

            2)当你提供 public void world() 方法的具体实现时,它会与你的方法 public void hello() 发生冲突,现在被覆盖的方法成为你的类的成员并且您的方法具有相同的参数列表,因此它将无法满足重载条件。

            所以这将使覆盖和重载功能都失败。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-10-15
              • 2016-09-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-09-18
              相关资源
              最近更新 更多