3

I'm just learning Java and design patterns and I am trying to get my head around when to use interfaces and abstract classes. I am wondering in the Strategy design pattern, why is it preferable to use an interface for the behaviour/algorithm subclasses rather than an abstract superclass?

Is it simply because there is no need for an abstract class because each behaviour/algorithm subclasses have their own implementation and therefore an abstract superclass would just provide extra functionality that won't be used?

Wouldn't an abstract class mean that there is an extra possibilty to use this extra functionality in the future if needed, for instance adding a method to the abstract superclass which is shared by the behaviour/algorithm subclasses if this is needed. Is there any reason why this is a bad idea?

Or is there another reason?

AmirA
  • 133
  • 2
  • 15
Jonny Shanahan
  • 351
  • 3
  • 13
  • 3
    Design patterns are about the general idea behind them and not necessarily the exact implementation. The interface and abstract class aspect are interchangeable. – Jeroen Vannevel Aug 02 '14 at 19:42
  • 2
    Interfaces also give you more flexibility since the implementing class can implement multiple interfaces or additionally extend a class. – Khary Mendez Aug 02 '14 at 19:45
  • If in doubt, use both :D make the abstract class implement the interface and extend from the abstract class – EpicPandaForce Aug 02 '14 at 20:09
  • It gets even more confusing when interfaces have associations to other interfaces. https://stackoverflow.com/questions/71095703/interface-to-interface-association-in-the-book-head-first-design-patterns – user32882 Feb 12 '22 at 21:23

4 Answers4

5

You should use a common interface for all your strategies and also create an abstract class that implements it. So, although all your strategies share an abstract class currently, your system is extendable because you can create unrelated strategies to this abstract one in the future.

Now using only some methods of the superclass is a decision you should make. It may be worthy or not.

note:: If you are using something similar to the Template Method Pattern you should check how to use hooks.

Stelium
  • 1,207
  • 1
  • 12
  • 23
  • Ok, so it is always better to limit extendability of the system where possible? (I just added the third paragraph which asks this actually). I guess that is veering off onto a different topic in itself – Jonny Shanahan Aug 02 '14 at 19:54
  • No, do not limit extendability. Why would you use an abstract class instead of an interface? Because your subclasses have some common code which you shouldn't duplicate. But if you only use an abstract class you cannot use a strategy that does not use this functionality ( unless you create empty methods, a whole different story). – Stelium Aug 02 '14 at 19:58
2

Before Java 8, interfaces had one big issue: it was impossible to add additional functionality (i.e. add new methods) without breaking every implementation of that interface. Abstract base classes were a way to avoid this problem.

Java 8 introduced default methods, which mostly addresses that issue. So with a modern Java system, interfaces provide much more flexibility without the downside.

Kevin Day
  • 16,067
  • 8
  • 44
  • 68
  • I was going to ask about this too actually, thanks for addressing this point. So does this mean that abstract classes are much less useful now than they were before Java 8? – Jonny Shanahan Aug 02 '14 at 23:32
  • @JonnyShanahan I think it all depends on the situation and the developer. Over the past twenty years of OO programming, I have found that I have dramatically reduced by use of inheritance and increased use of interfaces+composition instead. For me, this results in less coupled, more maintainable design. That said, I develop mostly in Java, and I do wish that there was a 'mix-in' capability in that language (it would eliminate a lot of boilerplate in a few broadly used patterns like property-change support). – Kevin Day Aug 03 '14 at 18:34
1

From an implementation point of view you can use both, interface and abstract class. The difference is in the purpose of use.

  • The main purpose of interfaces is to provide methods (i.e. communication points) to other classes. I.e. decoupling and inversion of dependency.
  • The main purpose of abstract classes is to help you build an inheritance structure upon them.

In the strategy pattern that means, if you use an AbstractState to define a common code base, you could still put an IState interface between the Context and the AbstractState to decouple them more.

Waog
  • 7,127
  • 5
  • 25
  • 37
0

There's no hard rule between using an interface or an abstract pattern. Use which ever is best in your situation.

If you have multiple Strategy implementations that are very similar of course you can use abstract classes or even subclass one of the Strategies.

dkatzel
  • 31,188
  • 3
  • 63
  • 67