3

I am working on a project with many someInterface - someInterfaceImpl-pairs. Some days ago I got the idea (probably inspired by reading some objective c code) to include the default implementations as an inner class. Now some colleagues (all with much more java experience than me) saw this idea - feedback was between shocked and surprised ("this is working?").

I googled around a bit but didn't find much evidence of usefulness of this "pattern" (personal i like it): pdf-paper and a faq about code style

What do you think - especially in those cases where an "default" implementation is tightly coupled to an interface.

Update i just found this: Java Interface-Implementation Pair

(see accepted answer)

Community
  • 1
  • 1
dermoritz
  • 12,519
  • 25
  • 97
  • 185

3 Answers3

8

The whole point of interfaces is to separate the users from the implementation (default or not). You defeat this by including the implementation as an inner class. You don't really save any lines of code and you clutter the API. You end up having to do things to hide the inner class from the users of the interface like making it private or default scope which it might be better to avoid. Also, what if your default implementation needs to change but you have published the interface as part of an API. This is a bad idea in that it does not have a lot of benefit and is an anti-pattern.

Finally, if you REALLY have a default implementation then maybe that should be a base class (rather than an interface) and other implementation extend the class and override behavior.

I thought this post gives an interesting discussion of a similar question: Question

Community
  • 1
  • 1
John B
  • 32,493
  • 6
  • 77
  • 98
  • 3
    If the default implementation needs to change then you'd drop a release with the new implementation--that wouldn't necessitate a change of the interface definition itself. You also wouldn't need to hide the implementation if it's *intended* for use as a default implementation. I don't see any *advantages* to doing it the way the OP describes, but I don't see the negatives you bring up as compellingly horrible, either--I just don't think it makes sense to lump them together and *force* a new interface distro for an implementation change. – Dave Newton Jun 04 '12 at 16:09
  • I was about to add an answer about base implementation vs abstract vs interface, you beat me to it :-) – ptyx Jun 04 '12 at 16:11
  • Horrible, maybe not. Bad, yes. It breaks the entire notion of an interface being the non-implemented API. If nothing else, it makes the source code of the interface less readable because it is cluttered with a default implementation which should be hidden from the users of the interface. – John B Jun 04 '12 at 16:16
  • you are right but in my special case the only reason to create interface is test-ability (gwt with mvp pattern). so the api will never be "published" and most likely there will never be another implementation but the mock. besides this - did anybody read the links i gave? there seem to be other advantages?! – dermoritz Jun 05 '12 at 06:38
1

I agree with the answer above but there are some cases where including the implementation is logical, like:

  • You are writing anonymous functions (when your interface has only one method and you are using it like anonymous functions in functional languages) than it is OK, but it is rare however.
Adam Arold
  • 29,285
  • 22
  • 112
  • 207
  • Radio 2 above is not an interface definition with a default implementation but an extension of an `abstract class` with a default implementation which is being overridden. Notice that since a default implementation was provided, it was done as an `abstract class` not an `interface` – John B Jun 04 '12 at 16:52
  • Again, the `ModifyListener` interface does not have a default implementation. You have created an anonymous inner class that implements the interface. – John B Jun 04 '12 at 18:50
  • And that's what I'm talking about. The question is about inner classes, he did not stated whether it was anonymous or not. – Adam Arold Jun 04 '12 at 21:44
  • thats a point :-) - but i am not talking about anonymous class. i am talking about "combo.addModifyListener(new ModifyListener.Impl())" – dermoritz Jun 05 '12 at 06:50
  • Ah. I read the question again. I missed the last sentence somehow, thanks for pointing out. – Adam Arold Jun 05 '12 at 08:11
1

If your default implementation is rather trivial and likely to stay that way, and if nothing extends it or is likely to, this is probably the way to go. You don't want to put it in its own file, and where else would you put it? I'd suggest making the class private with a public instance (assuming no state):

/** An interface a lot like java.util.Collection. */
public interface WhatEver  {
    private class Default  implements Whatever  {
        // Methods...
    }
    /** A default implementation that is always empty.  Suitable as a NULL value. */
    public final WhatEver  DEFAULT = new Default();
    // Rest of interface...

I don't think it would make any difference to execution (there's no data in the class instances), but you'd get better Javadoc. And you could use an anonymous class and save a line of code.

You might even want a few other "default" instances. For a collection-like interface, you might have one with a single, default entry, or an infinite number (hasNext always returns true) of the same default entry.

I think the key is the default implementations cannot depend on anything outside of the interface. Use no outside classes and interfaces unless they were referenced in the main body of the interface proper, and no outside classes extending the defaults. The interface becomes a bit more than the standard idea of an interface, but still stands on its own.

Another key point would be that you don't want too much code in one .java file, but you don't want too little, either.

RalphChapin
  • 3,108
  • 16
  • 18