15

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
  • 4
    suggestion on title: should I implement an interface directly or have the superclass do it Dec 19, 2012 at 2:34

3 Answers 3

21

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
  • 1
    +1 Far more clear than my answer! Dec 19, 2012 at 2:33
  • Additionally, if the interface was Heterotroph it seems reasonable to make Animal implement Heterotroph. If you expect a lot of other barking animals and want to treat them in same way another class BarkingAnimal extends Animal implements IBark would be the way to go.
    – scarfridge
    Dec 19, 2012 at 8:15
  • @scarfridge Actually I would expect animal to extend Heterotroph but thanks for your input
    – Karthik T
    Dec 19, 2012 at 8:22
2

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.

2

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
  • I think "AbstractC" (which does not exist in the question) in the the 2nd paragraph should be changed to "AbstractB". I can't edit to do that since edists must be at least 6 chars.
    – cellepo
    Sep 30, 2015 at 19:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.