While looking at some OOP materials, I thought of this question which confused me a little bit:
Consider having the following interface,abstract class, and a concrete class:
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() {
}
}
Class C won't compile unless it provides an implementation for method doStuff()
.
The question here:
1-Is doStuff()
method in class C an implementation to the interface A's method, or it is for the abstract method in class B ? to be more specific: How will the JVM
treat the function, as an invoked function of the interface or the abstract class ?
2-Is the abstract method doStuff()
in abstract class B considered to be an "implementation" for the doStuff()
method in interface A? so that makes it mandatory for class C to implement the abstract class's version of doStuff()
instead of the interface's ?
In an interface, all methods are
public
andabstract
.Knowing this, interface A's doStuff is actually
public abstract void doStuff()
. Which should look familiar, as Abstract Class B has the same method signature.To answer question 1, class B's
doStuff()
is the same as interface A'sdoStuff()
. Since all methods in Java are virtual, callingdoStuff()
will be the same regardless of if your C is declared as an A, a B, or a C.As for question 2, no. B's
doStuff()
is redundant code that doesn't actually do anything. C is implementing A'sdoStuff()
whether or not B declaresdoStuff()
.If you remove the
In your abstract class, then the childs that inherits this class HAVE TO implement this method.
Try to remove this method in Class B and see the results in class C
See section When an Abstract Class Implements an Interface in http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
For Question #1: The doStuff method in class C is the implementation of the doStuff method declaration to both B and C. because the doStuff method declaration in abstract class B and interface A has the same signature as each other. Actually, if B implements C, there is no need to declare doStuff method again.
For Question #2: No, the doStuff in B is just a declaration, not a method implementation. if B has no method implementation or additional method declaration, it is needless of class B. Basically, the abstract class is a kind of template containing high-level logic for the convenience of its subclasses.
I think that the explanation that you are looking for can be found here.
Question 1: Method in class C implements both. Since it only extends B however, it only needs to implement B abstract methods and unimplemented interfaces.
Question 2: It is not considered an implementation. Abstract classes do not have to implement all interfaces methods. Implementation in class C is mandatory (even if you don't have the abstract one in class B).
For instance of class B, C.doStuff() overrides B.doStuff() and implements A.doStuff(). All methods in java are invoked virtually. In fact there is no difference for user, whether C.doStuff() overrides B's method or A's. For jvm it will be different, because interface based invocation differs from class based.
UPD: This depends on type of a link, you are invoking from. different opcoded will be generated by javac: invokevirtual or invokeinterface