让我们一看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 ahd中重写,然后在接口 ThirdInterface 中再次覆盖,此接口最终由类 Demo继承。
在这种情况下,上述接口的哪个版本的show()方法将被Demo类合并?编译器如何在运行时动态解析特定版本的show()方法?
我觉得上面的接口继承层次结构(即ThirdInterface)中的最后一个接口中的show()方法将由编译器调用。如果是这样的话,上面两个接口中的show()方法(即FirstInaterface,SecondInaterface)是没用的,根本没用,因为它们是在接口内声明的,它们本身可以从不在任何地方都有自己的实现这种接口继承有用吗?
答案 0 :(得分:4)
只有方法实现可以覆盖,而不是接口中的方法规范。
在这种情况下,上述接口的哪个版本的show()方法将被Demo类合并?编译器如何在运行时动态解析特定版本的show()方法?
什么“版本”?方法签名是相同的,因此实际上只有一个方法规范。在运行时,将有一个实现类,只有该类中的方法实现才能实际调用。
如果是这样的话,上面两个接口中的show()方法(即FirstInaterface,SecondInaterface)是无用的,根本没用,因为它们是在接口内声明的,它们本身永远不会有自己的实现任何地方。
嗯,直接实现FirstInterface
的类怎么样?如果有的话,那些没有(技术)目的的是在子接口中“覆盖”方法。如果SecondInterface
和ThirdInterface
没有show()
方法,则会产生完全相同的语法效果。
但是,可以有一个合理的理由来覆盖子接口中的方法:提供不同的注释来解释方法契约中的语义更改。在Java API的集合框架中可以看到这样的示例:Set.add()
与Collection.add()
具有不同的契约,因为它增加了不应添加重复元素的限制。
答案 1 :(得分:1)
在这种情况下,上述接口的哪个版本的show()方法将被Demo类合并?怎么样? 编译器能够解析特定版本的show()方法 在运行时动态?
Demo demo=new Demo();
将调用该对象的 showMethod()
。所以这里的对象是类Demo
所以它的版本将被采用。
同样在编译时Demo
类需要声明show
和someConcreteMethod
方法,否则会变成编译时错误
我觉得上面接口继承层次结构(即ThirdInterface)的最后一个接口中的show()方法将是 由编译器调用
在界面中你实际上无法提供实现
如果是这样的话,上面两个接口中的show()方法(即FirstInaterface,SecondInaterface)是没用的,并且没有服务 目的,因为它们是在接口内声明的 他们自己永远不会有自己的实现。什么时候 这种接口继承有用吗?
是的,它只是声明..它也隐含地从父接口继承。所以,如果你写它或不它,它没有任何区别
答案 2 :(得分:1)
编译器不会选择任何接口的show()
方法:它将调用类的方法,就是全部。接口只是告诉必须在类中实现show方法。
覆盖接口中的方法是没用的(除非您添加注释)。接口继承仅在添加方法时才有用。
答案 3 :(得分:1)
我可以想到在子接口中覆盖超接口方法的唯一用途是文档。这样,您可以一目了然地看到此接口需要哪些方法,而不必检查超级接口以查找其他方法。如果你想澄清这个子接口的方法的使用,与在超接口或其他子接口中的使用形成对比,也可能是有意义的。
对于编译器,如果重写这些方法,则完全没有区别。
当然,如果你将AOP语言用作AspectJ,你可以将一个实现的方法注入一个接口,这个问题可能会变得相关。在这些情况下,编译器将从接口层次结构中获取第一个实现,从您的类实现的接口开始。
答案 4 :(得分:0)
show()
的{{1}}方法将被调用,因为当您编写Demo
时,在运行时JVM运行方法来自类....接口只是合同....他们不能给予实施
如果你不覆盖Demo demo=new Demo();
那么它将显示编译时错误......
show(); and someConcrete()
这些类型的实现是完全使用的,因为重用能力意味着在第一个接口中有一些行为,有些在第二个东西中在第三个...并且如果你想要一个具有所有这些功能和一些额外的类,那么你有2路..
1.制作另一个具有所有功能的界面。或者
2.创建一个界面并通过那些具有某些功能的界面吸收它并在界面中添加一些额外的东西..