[英]Java abstract class implements an interface, both have the same method
在看一些OOP资料时,我想到了这个让我有些困惑的问题:
考虑具有以下接口,抽象类和具体类:
package one;
public interface A {
void doStuff();
}
package one;
public abstract class B implements A {
public abstract void doStuff();
}
class C extends B{
public void doStuff() {
}
}
除非它提供方法doStuff()
的实现,否则C类不会编译。 这里的问题:
1- C类中的doStuff()
方法是接口A方法的实现,还是B类中抽象方法的实现? 更具体地讲:JVM如何将函数作为接口或抽象类的调用函数处理?
2-是否将抽象类B中的抽象方法doStuff()
视为接口A中 doStuff()
方法的“实现”? 因此这使得类C必须实现抽象类的doStuff()
而不是接口的版本?
对于问题1:C类中的doStuff方法是对B和C的doStuff方法声明的实现。这是因为抽象类B和接口A中的doStuff方法声明具有相同的签名。 实际上,如果B实现了C,则无需再次声明doStuff方法。
对于问题2:否,B中的doStuff只是一个声明,而不是方法实现。 如果B没有方法实现或附加的方法声明,则它不需要类B。基本上,抽象类是一种模板,为方便其子类而包含高级逻辑。
例如,对于B类,C.doStuff()覆盖B.doStuff()并实现A.doStuff()。 Java中的所有方法都是虚拟调用的。 实际上,对于C.doStuff()覆盖B的方法还是A的方法,用户没有任何区别。 对于jvm,它将有所不同,因为基于接口的调用与基于类的调用不同。
UPD:这取决于您从中调用的链接的类型。 :不同opcoded将由javac的生成invokevirtual或invokeinterface
在接口中,所有方法都是public
和abstract
。
知道这一点,接口A的doStuff 实际上是 public abstract void doStuff()
。 哪个应该看起来很熟悉,因为Abstract Class B具有相同的方法签名。
为了回答问题1,类B的doStuff()
与接口A的doStuff()
。 由于Java中的所有方法都是虚拟方法,因此无论您的C是声明为A,B还是C,调用doStuff()
都是相同的。
至于问题2,不。 B的doStuff()
是实际上没有执行任何操作的冗余代码。 C被执行A的doStuff()
乙是否声明doStuff()
如果删除
public abstract void doStuff();
在您的抽象类中,继承该类的子代必须实现此方法。
尝试在B类中删除此方法,然后在C类中查看结果
请参见http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html中的“当抽象类实现接口时”部分。
我认为您可以在此处找到所需的解释。
问题1:C类中的方法同时实现。 但是,由于它仅扩展B,因此仅需要实现B抽象方法和未实现的接口。
问题2:它不被视为实现。 抽象类不必实现所有接口方法。 C类的实现是强制性的(即使B类中没有抽象的实现)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.