views:

411

answers:

9

Is there a preferred method or style of creating a default implementation for interface methods? Suppose I had a commonly used interface where in 90% of the cases the functionality I wanted was identical.

My first instinct is to create a concrete class with static methods. I would then delegate the functionality to the static methods when I want the default functionality.

Here is a simple example:

Interface

public interface StuffDoer{
    public abstract void doStuff();
}

Concrete Implementation of methods

public class ConcreteStuffDoer{
    public static void  doStuff(){
        dosomestuff...
    }
}

Concrete Implementation using defualt functionality

public class MyClass implements StuffDoer{
    public void  doStuff(){
        ConcreteSuffDoer.doStuff();        
    } 
}

Is there a better approach here?

EDIT

After seeing a few of the proposed solutions I think I should be more clear about my intent. Essentially I am trying to work around Java not allowing multiple inheritance. Also to be clear I am not trying to make a statement about whether or not Java should allow multiple inheritance. I am just looking for the best way to create a default method implementation for classes implementing an interface.

+14  A: 

You could turn the interface into an abstract class, and provide default implementation for the methods as appropriate.

Update: I see, the multiple inheritance closes out changing the interface into an abstract class... in this case I would do the same as you. If the default implementation of the method(s) is not state-dependent, the best place for them is indeed in a static utility class. However, if there is state involved, I would consider object composition, which could even end up as something like a Decorator.

Péter Török
Yes, that's what the java.util Collections API does. I'd follow that as my model for design and implementation.
duffymo
My issue with that solution is when I am dealing with classes that already have different parents.
N8g
@N8g, if it is possible to refactor the class hierarchy, you could still gradually work towards this design. Otherwise, you end up with lots of duplicated code in the subclasses. Having the default implementation provided by an external class alleviates this problem, but is not the ideal solution. Of course, in the real world we can't always have ideal solutions :-(
Péter Török
I would agree in cases where I can combine the two lineages but this is a case where the classes that would implement the interface are , other than the interface, too far apart to share a common superclass. A good example is an interface like Printable. Maybe it has a few methods that are required and in most cases those methods will be very similar. Many of the classes may already extend more robust classes that are too dissimilar to reconcile.
N8g
@N8g, you are right. The problem hinges on multiple inheritance- not about using an interface rather than an abstract class. Removing my earlier comment. FWIW, the question topic is seriously misleading.
MAK
@MAK any suggestions for clearing up the topic?
N8g
@N8g, I think mentioning that this a problem concerning designing multiple-inheritance into a Java program might be a bit better.
MAK
I agree, I suggest you turn the interfaces into abstract classes and use them by composition. GOF style delegation is IMO the best approximation of multiple inheritance in Java.You might have to change your design slightly, but the alternative (a static inner class whose methods have to be called explicitly by all implementing classes) is quite error prone and more difficult to understand. It's probably more code too.
fhd
+1  A: 

I follow more or less the pattern I initially learned from Swing. I have an interface then I create either a "Base" or an "Adapter" class. For me, an adapter will often have do-nothing implementations for all of the interface methods, to allow an implementor to write just the methods they need while ignoring the others. A base will be an abstract class that provides convenient implementations for some of the interface methods - hopefully the "most likely" implementation.

For example, I have a SearchFilter interface that, among other things, has an apply(Collection<T>) method. That method will almost always loop through the collection and call the interface method boolean include(T item) to decide whether or not to keep or filter out the item. My SearchFilterBase provides that as an implementation for apply() and an implementor only has to write their include() logic.

Implementors are free, of course, to simply implement the whole interface themselves and not derive from the Base, which is the advantage over changing the interface to an abstract class, which forces them to use their single inheritance (This is the problem with java.util.Observable)


In response to N8g's comment - You can subclass the base or adapter but are not required to subclass -- you can implement the interface yourself from scratch. The base or adapter is provided as a convenience, implementing no-op methods so you don't have to do it, or implementing convenient common functionality in an abstract base class (like my SearchFilterBase class). The advantage this has over turning the interface into an abstract class is that you don't force inheritance from your abstract class.

Stephen P
I may be missing the intent of your approach but it seems like you would still need to subclass either your base or adapter class in these examples which gets back to the lack of multiple inheritance in Java that I am trying to work around here.
N8g
+1  A: 

I'd also use static methods to declare default functionality for stateless functionality.

For stateful functionality I'd prefer composition instead of inheritance. With composition and using delegates/adapters you can combine default functionality from many sources.

e.g.

public interface StuffDoer{
    void doStuff();
    void doOtherStuff();
}

public class MyStuffDoer implements StuffDoer{
    private final StuffDoer mixin;
    public  MyStuffDoer(StuffDoer mixin){
        this.mixin = mixin;
    }
    public void doStuff(){
        mixin.doStuff();
    }
    public void doOtherStuff(){
        mixin.doOtherStuff();
    }

}

public class MyStuffDoer2 implements StuffDoer{
    private final StuffDoer mixin1, mixin2;
    public  MyStuffDoer(StuffDoer mixin1, StuffDoer mixin2){
        this.mixin1 = mixin1;
        this.mixin2 = mixin2;
    }
    public void doStuff(){
        mixin1.doStuff();
    }
    public void doOtherStuff(){
        mixin2.doOtherStuff();
    }

}

For simple cases inheritance is ok as well, but it is not really very flexible.

Implementing multiple interfaces is also a case where this approach scales better.

public interface A{
    void doStuff();
}

public interface B{
    void doOtherStuff();
}

public class MyStuffDoer implements A, B{
    private final A mixin1;
    private final B mixin2;
    public  MyStuffDoer(A mixin1, B mixin2){
        this.mixin1 = mixin1;
        this.mixin2 = mixin2;
    }
    public void doStuff(){
        mixin1.doStuff();
    }
    public void doOtherStuff(){
        mixin2.doOtherStuff();
    }
}

You can't do this with abstract classes. I have used this composition approach on a few projects, and it worked quite fine.

Timo Westkämper
This is an interesting approach. Having the constructor take the class the implements the interface is a nice idea in that it makes things more explicit. I'm still not sure about the requirement for functionality that requires state. It seems like the state you would care about is the "MyStuffDoer" class and instantiating the mixin class doesn't address this. Why wouldn't your static methods not just take your MyStuffDoer class as a parm? More generically why not take an instance of the interface?
N8g
The state is in the mixin. And normally you can't access the state through the service signature, so giving the service itself as a parameter to the static method doesn't work. You can supply all the state to the method via separate parameters, but this way you will get quite verbose method signatures. Static methods are really good for stateless behavior, everything else should be handled by instance methods.
Timo Westkämper
+1  A: 

Static implementations have two problems:

  • you can't really find them with any static code analysis, like listing all the implementors, because the static method does not implement the interface, so you're forced to mention the default implementation in the javadoc

  • there's sometimes the need to have some state in the implementor, which cannot really be done within a static method

I thus prefer to use a concrete class which allows for both inheritance (if you're not limited by single inheritance) and composition, and call the resulting class *Peer, as it will normally be use with alongside the main class implementing the interface. The peer will implement the interface, and may also have a reference to the main object in case it needs to fire events in the name of the main class.

mkadunc
The title of the question is "Java Interface-Implementation Pair". I am limited to single inheritance. I am assuming state issues could be handled by static methods that take a parameter of the interface. This would allow me to call the static method and pass the calling object in. Of course I would then need to make sure that any methods/attributes needed for the default functionality were also defined in the interface but that seems like a reasonable thing to do anyway.
N8g
You're only limited by single inheritance if you want to extend something other than the concrete implementation (in which case you would use composition with the same class).
mkadunc
Passing the calling object into static methods will force you to expose the state of the object through the same public interface, which somewhat limits your implementation choices. Also, you will need fields in each implementation to store the state, whereas the peer class will store the state for you.
mkadunc
A: 

Composition trumps multiple inheritance in terms of flexibility. As with the Adapter Pattern (see the GOF book), it clearly allows us to adapt (morph) classes to different behaviors depending on callers request. See the IAdaptable interface in Eclipse RCP. Basically using interfaces is the same as using the Adapter Pattern built in in the Java language directly. But using adaptable classes is better than implementing multiple interfaces. Adaptable classes are more flexible, but they have some CPU overhead: the instanceof operator consumes less CPU than calling canAdapt(Class clazz). But in modern JVMs this could be false, since calculating instanceof with interfaces is more complex than calculating instanceof with inheritance.

PersicsB
+5  A: 

This is the approach I would take:

public interface MyInterface {

      MyInterface DEFAULT = new MyDefaultImplementation();

      public static class MyDefaultImplemenation implements MyInterface {
      }
 }

Of course, the MyDefaultImplementation may need to be private, or its own top level class, depending on what makes sense.

You can then have the following in your implementations:

 public class MyClass implements MyInterface {
        @Override
        public int someInterfaceMethod(String param) {
             return DEFAULT.someInterfaceMethod(param);
        }
  }

Its a bit more self-documenting, and ultimately more flexible, than a default implementation class that exists elsewhere but is not referenced by the interface. With this you can do things like just pass the default implementation as a method parameter when required (which you cannot do with the static methods).

Of course, the above only works if there is no state involved.

Yishai
A: 

Most of the time, I go with something like this:

public interface Something {
  public void doSomething();

  public static class Static {
    public static void doSomething(Something self) {
      // default implementation of doSomething()
      // the name of the method is often the same
      // the arguments might differ, so state can be passed
    }
  }

  public static abstract class Abstract implements Something {
    // the default abstract implementation
  }

  public static class Default extends Abstract {
    // the default implementation
    public void doSomething() {
      Static.doSomething(this);
    }
  }

  public static interface Builder extends Provider<Something> {
    // initializes the object
  }
}

I tend to use inner classes because these classes are really related, but you may also use regular classes.

Also, you might want to put the utility class (Static) in a separate file if the methods don't only concern the interface.


By the way, the problem with decorators is that they hide other implemented interfaces. In other words, if you have a something decorator the following is false new SomethingDecorator(new ArrayList<Object>()) instanceof List<?> if SomethingDecorator does not implement the interface of lists. You can work arround using reflection API and in particular using a Proxy.

Another good aproach are adaptors, as pointed by PersicsB.

Chris
+1  A: 

Dependency injection could provide the delegate, and specify a default implementation -- which could be overridden in unit tests.

For example, the Guice framework supports an annotation on the interface for its default implementation, which can be overridden by an explicit binding in unit tests.

@ImplementedBy( ConcreteStuffDoer.class )
public interface StuffDoer{
    void doStuff();
}

public class ConcreteStuffDoer implements StuffDoer {
    public void  doStuff(){ ... }
}

public class MyClass implements StuffDoer{
  @Inject StuffDoer m_delegate;
  public void  doStuff(){ m_delegate.doStuff(); }
}

This does introduce the requirement that creating an instance of MyClass requires a Guice method rather than simply new.

Andy Thomas-Cramer
A: 

If it your whatever function :-) works as a static then you don't need to delegate to it all since that means it doesn't need "this" - it's a utility function.

You can re-examine whether you really have overwhelming reason not to merge whatever you consider default implementations into the first abstract class that implements that interface - you know, the adaptation to reality :-)

Also, you can create secondary, protected virtual methods in abstract class that your interface-derived methods are going to call which giver you more control i.e. deriving class doesn't have to replace the methods and copy&paste 90% of it's code - it can just override a method that gets called from the main methods. Gives you a degree of behavioral inheritance.

ZXX