This is something that’s usually taught to first year Java students. Though I had a small mental blank about how it was implemented. I knew that to get around the ‘limitation’*, you could specify a class with multiple interfaces, but that was only half the solution. What about the implementation?
Surprisingly it was hard to get a clear answer from the fractal patterns that Google found, a lot of developers saying, “oh yeah, you need interfaces” but it didn’t sound like they knew themselves.
So, this was my way, probably duplicated a zillion times, but here you go, here’s a way:
We are going to have three classes, A, B & C (sorry for the lack of imaginative names here). Class C will extend both A & B. We’ll extra interfaces for A & B dubbed Ai & Bi respectively.
First an interface for the classes we are going to ‘extend’ from.
and now some implementation:
And now for our binding class, C. The class implements both interfaces, and takes in implementations of each of the super-classes as constructor arguments. The implementations of each method defined in the A and B interface is a delegate to the relevant A or B class that was injected in the constructor.
The call to the implementing a.aMethod() is effectively a super() call. You can then append your own extra implementation, or remove the delegating call and define your own.
So what about the diamond problem, when both A & B define a method that is named that same thing. In Java if you try to say a class implements interfaces that have duplicate signatures you’ll get a compile time error. If Ai and Bi both had a method called cMethod() then the C class would refuse to compile.
My research found other mentions. If you got lazy, you could have C extend A, and implement Bi. Then you wouldn’t have to write the interface Ai and C would be a little smaller since it would only inject the B implementation and have a bMethod() delegate.
Another way was to have the 2nd class as a static inner class. Although I have no issue with this implementation working, as soon as I see ‘inner’, I’m led to believe its re-use value becomes a bit more limited and certainly more cumbersome to refer to.
BTW, if you want to find a decent explanation of what to do and an interesting reading of a Mixin pattern implemented in Java, then see here.
* I say ‘limitation’ in quotes because apart from the well known diamond inheritance problem that crops up with multiple inheritance in C++, from what I read, using multiple inheritance could be a code smell. Certainly the ambiguity that comes from not knowing exactly which one will be called or whether or not you’ll know at compile time, or run-time is a concern. (Don’t delay the Bad-news)