【问题标题】:Two interfaces with same method signature implemented in Java class在 Java 类中实现的具有相同方法签名的两个接口
【发布时间】:2012-03-25 20:38:46
【问题描述】:

我有两个 Java 接口和一个实现类。

(我使用 Eclipse 直接运行程序,我没有尝试通过从命令行显式编译来检查任何编译器警告等。)

为什么它们可以毫无问题地运行?为什么 Java 允许这样做,即使它满足两个接口的“约定”但在实现类时会产生歧义?

更新了示例。

public interface CassettePlayer {
    void play();
}

public interface DVDPlayer {
    void play();
}

public class CarPlayer implements CassettePlayer,DVDPlayer{

    @Override
    public void play() {
        System.out.println("This plays DVD, screw you Cassette !");
    }

    public static void main(String args[]) {
        CarPlayer cp = new CarPlayer();
        cp.play();

        CassettePlayer firstInterface = new CarPlayer();
        firstInterface.play();

        DVDPlayer secondInterface = new CarPlayer();
        secondInterface.play();
    }
}

【问题讨论】:

  • 他们为什么会有问题?这就是问题;)
  • 如果您希望拥有一个带有sayHello 方法的抽象类,并让Sample 扩展抽象类。也不会有问题。
  • 谢谢哥们,我也有同样的问题...
  • 嘿它正在实例化接口:O

标签: java compiler-construction interface multiple-inheritance


【解决方案1】:

Java Language Specification, section 8.1.5 中特别允许这种情况:

一个类中的单个方法声明可以实现多个超接口的方法。例如在代码中:

interface Fish { int getNumberOfScales(); }
interface Piano { int getNumberOfScales(); }
class Tuna implements Fish, Piano {
   // You can tune a piano, but can you tuna fish?
   int getNumberOfScales() { return 91; }
}

Tuna 类中的方法getNumberOfScales 的名称、签名和返回类型与接口Fish 中声明的方法相匹配,也与接口Piano 中声明的方法相匹配;它被认为是实现两者。

文本接着指出,如果方法签名具有不同的返回类型,例如 doubleint,则无法在同一个类中实现这两个接口,并且会出现编译时错误生产出来的。

【讨论】:

    【解决方案2】:

    对于这个问题,有必要了解接口的用途。

    接口是一种“契约”,因此人们知道在具有该接口的类中强制实现了哪些方法。

    因此,如果您需要一个实现“DVDPlayer”的类(因为您需要“play()”方法),您会找到 CarPlayer。实现 CassettePlayer 的类的需要也是如此。这就是技术解释。

    当然,在您的语义编码中,您应该确保 CarPlayer 的方法“play()”满足 DVDPlayer 和 CassettePlayer 的语义。我认为在实际应用中这将是一个不好的做法。

    当然,在您的示例中,让两个接口声明相同的方法是个坏主意。更实际地,您应该使用方法“play()”创建一个接口“Player”,并拥有两个从 Player 继承的更具体的接口 DVDPlayer 和 CassettePlayer(具有用于 DVD 和磁带的特定方法)。 另一方面,如果您不需要 DVD 或磁带的特定方法,那么您不需要两个不同的接口,只实现一个相同的方法 - 只需使用一个接口 Player,就足够了。

    【讨论】:

      【解决方案3】:

      在这种情况下,没有问题,因为两个接口具有相同的方法签名。但是这个呢?

      interface Animal {
          public void eat() throws IOException;
      }
      
      interface Plants {
          public void eat() throws NullPointerException;
      }
      

      编译器选择了哪一个?为什么代码下面会报错?

      public class Test implements Animal, Plants {
      
          public void eat() throws IOException {
      
          }
      }
      

      编译器说:异常 IOException 与 Plants.eat() 中的 throws 子句不兼容

      【讨论】:

        【解决方案4】:

        没有冲突,因为它们都指定了相同的契约,实现类只提供一个方法,当通过任一接口引用时调用该方法。

        【讨论】:

          【解决方案5】:

          为什么不呢?该类满足两个接口定义的契约。

          【讨论】:

            【解决方案6】:

            该类实现了这两个接口 - 所以没问题。当然,在可能导致意外行为的更复杂情况下,应避免此类事情。

            【讨论】:

              【解决方案7】:

              以下页面包含一个类的示例 它实现了两个具有

              的接口

              1) 相同的变量名 2) 各接口方法相同。

              http://www.j2eeonline.com/java-tm-fundamentals-II/module2/interface-ambiguous-fields.jsp

              【讨论】:

                猜你喜欢
                • 2014-05-06
                • 1970-01-01
                • 2011-12-13
                • 2011-07-26
                • 2015-10-19
                • 2013-02-18
                • 2015-03-11
                • 2022-01-22
                • 2018-11-04
                相关资源
                最近更新 更多