3

Composition over inheritance is an old trend or even accepted state of the art in object oriented programming. It would be even easier to use in Java, if there were language support for delegation. Our IDEs, like eclipse, allow for easy generation of delegating methods, but the result is terrible code clutter. I would rather like to see something like

class ExtendedList<T> implements List<T> {
  List<T> values = new ArrayList<T>();
  delegate values.*;
  ...
}

where delegate is a new language keyword that is nothing but a shortcut for what the IDE does explicitly when you ask it to delegate to all methods of the field values.

I could go on to compare this with inheritance and how the result could be much the same, given interfaces, but more explicit and allowing fine grained, explicit "multiple inheritance", but this discussion must have happened already sometime in the past in some Java mailing list. Yet I could only find 15 year old links, for example on beust.com and citeseer describing ideas very similar to what I have in mind.

I think this is (a) really useful and (b) trivial to implement in a compiler, yet in 15 years nothing has appeared in Java.

So my question is: What am I missing? Is there a major hurdle in implementing this that I am not aware of?

As an aside: I would love to get good pointers to, for example, Java/JCP/JSR/whatever where this was discussed. I did not manage to find some.

As requested, let me try another example:

class FileWithMetas extends OutputStream implements Map<String,String> {
  final OutputStream out;
  delegate out.*; // takes care of "extend OutputStream"
  final Map<String,String> metas = new HashMap<>();
  delegate metas.*; // takes care of "implements Map"
  public FileWithMetas(...) {
    this.out = new FileOutputStream(...);
  }
  @Override //explicitly re-implement the delegated out.close()
  public void close() {
    //serialize the metas, for example
    out.close(); // with classic inheritance this would be super.close()
  } 
}

This will look very much like multiple inheritance in the end, but as mentioned: the delegation is just syntactic sugar replacing delegation methods generated by the IDE and except for slightly different error messages, the compiler should behave exactly like that. In fact I think this could replace inheritance completely (not that I am asking for it) --- given we keep interfaces, of course, which allow us to separate types from implementation.

Harald
  • 181
  • 6
  • I don't see how this is meaningfully different from inheritance, except that you can't assign one of these to an `ArrayList`. The entire point of composition over inheritance is to provide a more flexible, resilient abstraction. This is just composition to follow the letter of the rule and not the spirit of the rule. – Telastyn Feb 08 '15 at 15:27
  • Can you include a code example and explanation showing how this might be used in a practical context? Also, read [this answer by Eric Lippert](http://stackoverflow.com/a/4914207/102937), where he discusses some of the practical reasons why features don't always make it into a language. – Robert Harvey Feb 08 '15 at 15:36
  • @Telastyn surely we do not want to assign to an ArrayList, but by using `delegate` we implement the `List` interface as advertised in a single line of code and thus can assign to `List`. The `...` then add whatever makes up the Extended in `ExtendedList`. – Harald Feb 08 '15 at 15:41
  • 1
    @Harald - I understand that, but "delegate to base class" is semantically no different than inheritance without override. You're not gaining anything. – Telastyn Feb 08 '15 at 19:04
  • @Telastyn sure he is gaining something. If you inherit from `ArrayList` then the implementation detail (that you use an `ArrayList`) leaks out of the class. You only want the clients to see the `List` interface, so that you can switch the list-implementation when required without affecting the clients. – TmTron Oct 29 '15 at 12:36

1 Answers1

-3

Your suggestion can't handle the delegation target being null which would go against everything Java is. If you try to handle this by forcing the object to be constant then it is just a less readable variant of multiple inheritance. By the way, multiple inheritance is already in Java 8.

Also you can easily get the same result by making the list public like this:

class ExtendedList<T>{
  const public List<T> values = new ArrayList<T>();
}

Then you can use the same methods and when you want to use the interface just pass the List object directly.

Johan
  • 254
  • 2
  • 3
  • 1
    Java 8 has mixins through default interface methods, not really full-fledged multiple inheritance. – acelent Feb 08 '15 at 18:49