Multiple Inheritance in Java

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.

   1: public interface Ai {

   2:     public void aMethod();

   3: }

   1: public interface Bi {

   2:     public void bMethod();

   3: }

and now some implementation:

   1: public class A implements Ai {

   2:  

   3:     public void aMethod() {

   4:         System.out.println("aMethod");

   5:     }

   6:     

   7: }

   1: public class B implements Bi {

   2:     public void bMethod() {

   3:         System.out.println("bMethod");

   4:     }   

   5: }

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.

   1: public class C implements Ai, Bi {

   2:     private final Ai a;

   3:     private final Bi b;

   4:     

   5:     public C(Ai a, Bi b) {

   6:         this.a = a;

   7:         this.b = b;

   8:     }

   9:  

  10:     public void aMethod() {

  11:         a.aMethod();

  12:     }

  13:  

  14:     public void bMethod() {

  15:         b.bMethod();

  16:     }

  17: }

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.

Other ways

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.

Notes

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)

Leave a Reply