Java抽象类实现了一个接口,两者都有相同的方法

时间:2013-03-04 13:00:09

标签: java oop interface abstract-class multiple-inheritance

在看一些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() {

    }
 }

C 除非为方法doStuff()提供实现,否则将无法编译。 这里的问题是:

1 - 类 C 中的doStuff()方法是接口 A 方法的实现,或者是类 B ?更具体一点:JVM将如何 将函数视为接口或抽象类的调用函数?

2 - 抽象类 B 中的抽象方法doStuff()被认为是接口 A doStuff()方法的“实现” ?所以这使得 C 类必须实现抽象类的doStuff()版本而不是接口的?

5 个答案:

答案 0 :(得分:4)

对于问题#1:C类中的doStuff方法是对B和C的doStuff方法声明的实现,因为抽象类B和接口A中的doStuff方法声明具有彼此相同的签名。实际上,如果B实现C,则不需要再次声明doStuff方法。

对于问题#2:不,B中的doStuff只是一个声明,而不是方法实现。如果B没有方法实现或附加方法声明,则不需要B类。基本上,抽象类是一种包含高级逻辑的模板,以方便其子类。

答案 1 :(得分:1)

对于B类的例子,C.doStuff()重写B.doStuff()并实现A.doStuff()。虚拟地调用java中的所有方法。事实上,用户没有区别,无论C.doStuff()是否覆盖B的方法或A。对于jvm,它会有所不同,因为基于接口的调用与基于类的调用不同。

UPD:这取决于您要调用的链接类型。 javac将生成不同的opcoded:invokevirtualinvokeinterface

答案 2 :(得分:1)

在界面中,所有方法都是publicabstract

了解这一点,界面A的doStuff实际上是 public abstract void doStuff()。这应该看起来很熟悉,因为抽象类B具有相同的方法签名。

要回答问题1,B类的doStuff()与接口A的doStuff()相同的。由于Java中的所有方法都是virtual,因此无论您的C是声明为A,B还是C,调用doStuff()都是相同的。

关于问题2,没有。 B doStuff()是冗余代码,实际上并没有做任何事情。 C正在实施A doStuff(),无论B是否声明doStuff()

答案 3 :(得分:0)

如果删除

 public abstract void doStuff();

在抽象类中,继承此类的子项必须实现此方法。

尝试在B类中删除此方法,并在C类中查看结果

参见抽象类在http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

中实现接口时的部分

答案 4 :(得分:0)

我认为可以找到您正在寻找的解释here

问题1:C类中的方法实现了两者。因为它只扩展了B,所以它只需要实现B抽象方法和未实现的接口。

问题2:它不被视为实施。抽象类不必实现所有接口方法。 C类的实施是强制性的(即使你没有在B类中有抽象的)。

相关问题