Is there a difference between
public class A extends AbstractB implements C
{...}
versus…
public class A extends AbstractB
{...}
abstract class AbstractB implements C
{...}
I understand that in both cases, class A will end up conforming to the interface. In the second case, AbstractB
can provide implementation for interface methods in C
. Is that the only difference?
If I do NOT want to provide an implementation for any of the interface methods in AbstractB
, which style should I be using? Does using one or the other have some hidden ‘documentation’ purpose?
1
It all depends on if AbstractB implements C
semantically. I.e if it makes sense semantically for AbstractB
to implement C
, then go for it.
If we take concrete examples the semantic difference becomes clear.
If A = Dog , AbstractB = Animal, C = IBark
Only choice that makes sense is
class Dog extends Animal implements IBark{
This makes no sense, since this would imply that all animals bark.
class Animal implements IBark{
The other differences come into play if you have more than just class A
inheriting from AbstractB
. In #1 they need not implement C, in #2 they are all forced to implement C.
3
The easy way to determine the proper inheritance relationship is not to look at the classes themselves, but at the code that calls methods on those classes. Somewhere in your code you have something like AbstractB b = new A();
or otherObject.addAbstractB(this);
. Either way, you later use that AbstractB
reference to make various method calls.
In that situation, are you going to want to call methods of C
? If so, then AbstractB
should implement C
. If not, it shouldn’t. If you don’t have any situations like that, then you don’t need inheritance, and should refactor to use composition instead because it is much looser coupled.
It’s not a “hidden” documentation purpose. It allows you to cast AbstractB and all of it’s subclasses to C. There are actually three styles.
public class A extends AbstractB implements C
public class AbstractB
I’d use this one if AbstractB didn’t logically implement C. Even if it doesn’t provide the methods, it could have meaning. Such as Dog extends Animal implements Wag. It doesn’t make sense for all animals to Wag. Note that this approach doesn’t actually preclude AbstractB from providing the implementation.
public class A extends AbstractB
public AbstractB implements C
I’d use this one if I wanted all subclasses to implement the interface AND it makes sense for all of them to do so. Such as Beagle extends AbstractDog implements Wag.
public class A extends AbstractB implements C
public class AbstractB implements C
This one is redundant but might add clarity.
1