Java – Multi Inheritance in Java Explained

genericshierarchyjavajava8multiple-inheritance

Let's say I've got a generic java class Filter<InputType, OutputType> which receives an input object and transforms it to an output object.

Now I've got two other classes (NoInputFilter<OutputType>, NoOutputFilter<InputType>) which should do the same except they haven't an InputType respectively an OutputType.

Now the three classes have some functionality in common. The Filter class should handle the input object the same way like the NoOutputFilter does, and it should handle the output object the same way like the NoInputFilter does.

So I've got something like this in terms of functionality, where B is Filter:

Three sets

Now, Java doesn't allow to inherit from multiple classes. Is there a design pattern to do something like this?

My first approach was to have two interfaces. One interface for the input, one interface for the output. The Filter class implements both. But this way I have to implement the interfaces two times each.

Then I thought about to give the Filter class (which implements the two interfaces) instances of NoOutputFilter and NoInputFilter and just call the right method instead of have duplicated code. But this breaks the semantics, has a lot of boilerplate code, and isn't a very clean approach in my opinion. Here a little demonstration:

class Filter<InputType, OutputType> implements INoOutputFilter<InputType>, INoInputFilter<OutputType> {
  private final INoOutputFilter<InputType> noOutputFilter;
  private final INoInputFilter<OutputType> noInputFilter;

  public void InputType setInput(InputType input) {
     noOutputFilter.setInput(input);
  }

  public OutputType getOutput() {
     noInputFilter.getOutput();
  }

  [...]
}

The last idea was to turn the class hierarchy up site down:

public class Filter<InputType, OutputType>
public class NoInputFilter<OutputType> extends Filter <Void, OutputType>
public class NoOutputFilter<InputType> extends Filter <InputType, Void>

This way, the classes behaves the right way, no duplicated code, but e.g. the NoOutputFilter has a public Void getOutput() method. Even though you can not instantiate something from Void, the API of those two classes are wrong. This would be something like this:

enter image description here

So this isn't a nice approach as well.

Do you have any hint how I could solve this in Java? Is there a design pattern for this?

Best Answer

First of all, Java 8 introduced Default Methods, which is in fact multi-inheritance in Java.

History showed that complicated inheritance structure is cancer. You should favor composition over inheritance. In this case you are mixing input filter with output filter to create artificial bi-directional filter parent. Not clean for me at all.

I don't have your full picture, but from what you described, I would consider two interfaces: InputFilter and OutputFilter. Eventual Bi-directional filter implementation would implement both interfaces.

And if there would be some common functionality, I would extract that common logic into separate class and use it as dependency.