【问题标题】:When interface inheritance in Java is useful?Java中的接口继承什么时候有用?
【发布时间】:2011-11-04 10:23:05
【问题描述】:

让我们看一下Java中的以下代码。

interface FirstInaterface
{
    public void show();
}

interface SecondInterface extends FirstInaterface
{
    @Override
    public void show();

    public void someConcreteMethod();
}

interface ThirdInterface extends SecondInterface
{
    @Override
    public void show();
}

final class Demo implements ThirdInterface
{
    @Override
    public void show()
    {
        System.out.println("The show() method invoked");
    }

    @Override
    public void someConcreteMethod()
    {
        System.out.println("The someConcreteMethod() method invoked");
    }

}

final public class Main
{
    public static void main(String[] args)
    {
        Demo demo=new Demo();
        demo.show();
        demo.someConcreteMethod();
    }
}

上面的 Java 代码显示了接口的多级继承,其中 ThirdInterface 上面有两个接口。 show() 方法首先在接口 SecondInaterface 中被重写,然后在接口 ThirdInterface 中再次被重写,该接口最终被类 Demo 继承强>。


在这种情况下,上述接口中的哪个版本的 show() 方法将被类 Demo 合并?编译器如何在运行时动态解析特定版本的 show() 方法?


感觉上面接口继承层次结构中最后一个接口(即ThirdInterface)中的show()方法会被编译器调用。如果是这样的话,上面两个接口(即FirstInaterface,SecondInaterface)中的show()方法是没有用的,根本没有任何作用,因为它们是在接口中声明的,它们本身永远不会在任何地方都有自己的实现。这种接口继承什么时候有用?

【问题讨论】:

    标签: java oop inheritance


    【解决方案1】:

    只有方法实现可以覆盖,而不是接口中的方法规范。

    在这种情况下,上述接口中的哪个版本的 show() 方法将被类 Demo 合并?编译器如何在运行时动态解析特定版本的 show() 方法?

    什么“版本”?方法签名是相同的,因此实际上只有一种方法规范。在运行时,会有一个实现类,只有该类中的方法实现才是真正被调用的。

    如果是这样,那么上面两个接口(即FirstInaterface,SecondInaterface)中的show()方法是没有用的,根本没有任何作用,因为它们是在接口中声明的,它们本身永远不可能有自己的实现任何地方。

    嗯,直接实现FirstInterface 的类呢?如果有的话,没有(技术)目的的是在子接口中“覆盖”方法。如果SecondInterfaceThirdInterface 没有show() 方法,则其语法效果完全相同。

    但是,覆盖子接口中的方法可能有一个正当理由:提供不同的注释来解释方法协定中的语义变化。这方面的示例可以在 Java API 的集合框架中看到:Set.add()Collection.add() 具有不同的协定,因为它添加了不应添加重复元素的限制。

    【讨论】:

    • 什么“版本”?方法签名是相同的,因此实际上只有一种方法规范。在运行时,会有一个实现类,只有该类中的方法实现才是真正被调用的。这真是一个很好的解释。
    【解决方案2】:

    在这种情况下,上述接口中的哪个版本的 show() 方法将被类 Demo 合并?怎么样 编译器能够解析特定版本的 show() 方法 在运行时动态地运行?

     Demo demo=new Demo();
    

    showMethod() 的对象将被调用。所以这里的对象属于Demo 类,因此将采用其版本。

    同样在编译时Demo类需要声明showsomeConcreteMethod方法,否则会变成编译时错误


    感觉上面接口继承层次结构中最后一个接口(即ThirdInterface)中的show()方法会是 由编译器调用

    在接口中你实际上无法提供实现


    如果是这样的话,那么上面两个接口(即FirstInaterface,SecondInaterface)中的show()方法是没用的,不服务 根本目的,因为它们是在接口中声明的,所以它们 他们自己永远无法在任何地方拥有自己的实现。什么时候 这样的接口继承有用吗?

    是的,它只是声明......它也隐式地从父接口继承。所以无论你写还是不写都没有任何区别

    【讨论】:

      【解决方案3】:

      编译器不会选择任何接口的show()方法:它会调用类的方法,仅此而已。接口只是告诉我们必须在类中实现一个 show 方法。

      在接口中重写方法是没有用的(除非你添加注释)。接口继承只有在添加方法时才有用。

      【讨论】:

      • "接口继承只有在添加方法时才有用。"能否请您解释一下,换句话说,我发现它有点重要和有用。
      • 还有什么词?添加方法就像添加方法一样?我的意思是,上面的两个接口都有 show() 方法……为什么?派生接口中的 show() 方法有什么用?没有。如果您出于某种原因需要从接口继承,您的派生接口应该提供新的行为、更多的方法、新的方法,就像添加的方法一样;D
      【解决方案4】:

      我能想到的在子接口中覆盖超接口方法的唯一用途是文档。这样一来,您就可以一目了然地看到该接口需要哪些方法,而不必检查超级接口来查找其他方法。如果您想澄清此子接口的方法的使用与在超级接口或其他子接口中的使用相比,这也可能是有意义的。

      对于编译器来说,如果你覆盖这些方法,根本没有区别。

      当然,如果您将 AOP 语言用作 AspectJ,您可以将已实现的方法注入接口,这个问题可能会变得相关。在这些情况下,编译器会采用它在接口层次结构中遇到的第一个实现,从您的类实现的接口开始。

      【讨论】:

        【解决方案5】:

        Demoshow() 方法将被调用,因为当您编写 Demo demo=new Demo(); 时,在运行时来自类的 JVM 运行方法......接口只是合同......他们不能提供实现
        如果你不覆盖show(); and someConcrete() 那么它会显示一个编译时错误...

        When such kind of interface inheritance is useful?   
        

        这些类型的实现由于重用能力而被完全使用,这意味着在第一个接口中有一些行为,在第 2 部分中有一些在第 3 部分中......如果你想要一个具有所有这些功能和一些额外功能的类,那么你有2路..
        1. 制作另一个具有所有这些功能的界面。或者
        2. 做一个接口,通过那些有一些功能的接口来继承它,并在你的接口中添加一些额外的..

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-10-19
          • 1970-01-01
          • 1970-01-01
          • 2010-10-13
          • 2020-08-23
          • 2011-03-05
          • 1970-01-01
          相关资源
          最近更新 更多