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)

Related posts:

  1. Inline Java In Perl
  2. Effective Java Programming Language Guide
  3. Building Java Applications with Windows Azure
  4. More on Enums
  5. Unit Testing Private Methods
This entry was posted in Java. Bookmark the permalink.

Leave a Reply