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?

Benjamin Hodgson
  • 4,488
  • 2
  • 25
  • 34
c_maker
  • 8,250
  • 4
  • 35
  • 53

3 Answers3

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.

Karthik T
  • 948
  • 6
  • 10
  • 1
    +1 Far more clear than my answer! – Hand-E-Food Dec 19 '12 at 02: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 '12 at 08:15
  • @scarfridge Actually I would expect animal to extend `Heterotroph` but thanks for your input – Karthik T Dec 19 '12 at 08:22
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.

Jeanne Boyarsky
  • 1,746
  • 14
  • 21
  • 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 '15 at 19:02
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.

Karl Bielefeldt
  • 146,727
  • 38
  • 279
  • 479