Composition – Alternatives to Overriding a Method

composition

If we should favor composition over inheritance, the data part of it is clear, at least for me.

What I don't have a clear solution to is how overwriting methods, or simply implementing them if they are defined in a pure virtual form, should be implemented.

An obvious way is to wrap the instance representing the base-class into the instance representing the sub-class. But the major downsides of this are that if you have say 10 methods, and you want to override a single one, you still have to delegate every other methods anyway. And if there were several layers of inheritance, you have now several layers of wrapping, which becomes less and less efficient. Also, this only solve the problem of the object "client"; when another object calls the top wrapper, things happen like in inheritance. But when a method of the deepest instance, the base class, calls it's own methods that have been wrapped and modified, the wrapping has no effect: the call is performed by it's own method, instead of by the highest wrapper.

One extreme alternative that would solve those problems would be to have one instance per method. You only wrap methods that you want to overwrite, so there is no pointless delegation. But now you end up with an incredible amount of classes and object instance, which will have a negative effect on memory usage, and this will require a lot more coding too.

So, are there alternatives (preferably alternatives that can be used in Java), that:

  • Do not result in many levels of pointless delegation without any changes.
  • Make sure that not only the client of an object, but also all the code of the object itself, is aware of which implementation of method should be called.
  • Does not result in an explosion of classes and instances.
  • Ideally puts the extra memory overhead that is required at the "class"/"particular composition" level (static if you will), rather than having every object pay the memory overhead of composition.

My feeling tells me that the instance representing the base class should be at the "top" of the stack/layers so it receives calls directly, and can process them directly too if they are not overwritten. But I don't know how to do it that way.

[EDIT] It seems that many people reading this question think that I am debating if I should use Composition or Inheritance, and that "guiding" me to the one or the other will solve my problem. This is not the case. I always use inheritance when I can, for the simple fact that composition requires more coding, and also more memory. No need to convince me that inheritance is not evil.

I have a very good reason to want to use composition. I want to create a system that model domain objects that can "change nature" over time. That is they can both gain and loose functionality/properties over time, as a result of some actions. This is a lot more natural when modeled as composition.

If the components that can be dynamically added and removed where composed only of properties, it would be easy. In fact I have already found 14 different possible designs that support that case, with varying compromise on code complexity, memory usage, and speed.

The real problem comes when all those components need to be aware of each other, and talk to each other. This is not required when they are just "beans" (in the Java sense). I want to know if there are any, and hopefully several, ways of allowing the components to talk to each other, and more specifically how to have several components of the same type, where one serves as base-class and the others progressively override some of it's methods.

I can see two ways to simulate the overriding present in inheritance.

The first is to have a base component, and all overriding components are built as wrapper on top of another component of the same type. Like that, you can choose at runtime which hierarchy of components you want. This is like pipes and filters. But the problem is that with inheritance, not only can the derived class call methods of the base class, but it works the other way around too. A base class can declare a pure virtual method, which is implemented by the sub-class, and the base class can call this method. I don't see how to accomplish that using whole component wrapping. Also, if we have N inheritance/wrapping layers, then calls to method of the base component then gets N level of delegation, even if the method was not overwritten by any of the wrapping components.

The other alternative, like I said in "One extreme alternative …", is to do it like above, but forcing each component to contain a single method. In that case we solve the problem of the base-class not seeing/calling the methods of the derived classes, for all methods, except it's own method. So it works now correctly for all cases except for recursion. But the price we pay in memory consumption is high, at least in Java. And Java isn't "functional", so there is a lot of syntax overhead to turn every object method into an individual object.

If there any better alternatives then the two mentioned above, I would like to know about it.

Best Answer

"favor composition over inheritance" doesn't mean never use inheritance, but just don't use inheritance when composition will work. IMO, the need of overwriting justifies the use of inheritance.