【问题标题】:Can I use the same name for different methods in different interface?我可以在不同的接口中为不同的方法使用相同的名称吗?
【发布时间】:2015-01-23 12:04:49
【问题描述】:

我只是为了一些研究目的而学习 Java。 我对Java中的接口机制有疑问。 我不知道将接口理解为某种特殊的抽象类是否正确;但我很困惑编译时使用的是哪种方法“pr(int _i)”:

public interface A {
    int flagA=0;
    void pr(int _i);
}

另外一个接口B是这样的:

public interface B extends A{
    int flagB=0;
    double pr(int _i);
}

然后我实现了一个使用接口 A 和 B 的类:

public class inter1 implements A,B {
    void pr(int _i){...};
    double pr(int _i){...};
}

无法正确编译。当我使用接口 B 时,这里不会对接口 A 形成覆盖。但是返回类型是否足以区分两种方法?

我已经查阅了 Bruce Eckel 的 Thinking in Java,但没有找到任何有用的东西。

感谢您的宝贵时间!

【问题讨论】:

  • 一条评论:_i 不是典型的 java 命名约定
  • ===Update 2015-01-27=== 我找到了一种方法来实现我想要实现的目标:简单来说我在 Class inter1 中设置了一个私有内部类 internalClass1 inter1$internalClass1.class , 分别实现 B:code public class inter1 implements A { //重写接口 A 中的方法 pr void pr(int _i){...}; class internalClass1 implements B{ //重写接口 B 中的方法 pr double pr(int _i){...}; } }code 它适用于我的目的,希望它也能帮助你。
  • 另一个相关问题是:stackoverflow.com/questions/7604030/…

标签: java interface return-type overriding


【解决方案1】:

只有不同的返回类型是不够的。

这是因为编译器不知道调用哪个方法。如果丢弃任何返回值,则尤其如此。

【讨论】:

  • 在 JVM 级别,返回类型是签名的一部分,并且可以重载。这对于 Java 5 中用于返回类型协变的桥接方法的实现至关重要。但是,在 Java 语言级别,返回类型不是签名的一部分。
  • @ChrisJester-Young 确实是这样。为什么不作为答案?我故意让我的很简单。
  • @ChrisJester-Young,有什么书我可以参考这些问题吗?谢谢!
  • @Henr.L 我能想到的唯一能充分解释这一点的书是Java 语言规范。但是,它绝对不是为 Java 初学者设计的。它适用于实现 Java 编译器和运行时的人。
  • @ChrisJester-Young 谢谢,我看到另一个人在下面提到了同一本书。我深表感谢。希望有一天我可以使用那本书。
【解决方案2】:

Java 语言规范section on Requirements in Overriding and Hiding 解释了在覆盖方法时返回类型应该如何关联:

如果返回类型为 R1 的方法声明 d1 覆盖或隐藏了返回类型为 R2 的另一个方法 d2 的声明,则 d1 必须是 d2 的返回类型可替换(第 8.4.5 节),否则会出现编译时错误发生。

Section 8.4.5 解释了返回类型如何被替换:

如果以下任何一项为真,则返回类型为 R1 的方法声明 d1 可返回类型可替换

  • 如果 R1 是 void,那么 R2 是 void

  • 如果 R1 是原始类型,则 R2 与 R1 相同。

  • 如果 R1 是引用类型,则以下情况之一为真:

    • R1,适配d2的类型参数(§8.4.4),是R2的子类型。

    • 可以通过未经检查的转换 (§5.1.9) 将 R1 转换为 R2 的子类型。

    • d1 与 d2 的签名不同(第 8.4.2 节),并且 R1 = |R2|。

因此,如果方法pr 的返回类型为void,则在接口B 中被覆盖的方法也必须返回void。如果返回类型为int,则被覆盖的方法也必须返回int。对于引用类型,返回类型应该是子类型或可转换为子类型:

interface A {
   int flagA = 0;

   Number pr(int _i);
}

interface B extends A {
   int flagB = 0;

   Integer pr(int _i);  // compiles fine
}

另一方面,

interface A {
   int flagA = 0;

   Integer pr(int _i);
}

interface B extends A {
   int flagB = 0;

   Number pr(int _i);  // does not compile
}

【讨论】:

  • 感谢您的耐心和参考,可惜只能选择一个答案。我深表感谢。 :-)
  • 这个答案真的很有帮助!学到很多,谢谢!
【解决方案3】:

你定义的接口B也会有编译错误,

因为方法 pr()[in interface B] 在接口 A 中实现了 pr(),但返回类型不会根据实现方法规则兼容

在实现方法中,返回类型应该是相同类型或instanceOf操作返回真值的任何类型。(协变类型)

此外,只有在以下条件下才能区分2种方法

  • 参数数量
  • 参数类型
  • 这些参数的顺序

希望这会有所帮助!

祝你好运!

【讨论】:

    【解决方案4】:

    你不能编写两个相同的方法,只在同一个类中改变返回类型。

    方法重载具有不包含返回类型的不同规则(重载方法可以有不同数量的参数参数类型和参数顺序)

    而且您的界面也不会被编译,因为它没有以正确的方式覆盖方法。 协变类型仅适用于方法覆盖而不适用​​于方法重载

    【讨论】:

      猜你喜欢
      • 2019-06-13
      • 1970-01-01
      • 1970-01-01
      • 2013-11-26
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多