American in Spain

Multiple Inheritance in Java

October 23, 2006

I have come up with a way to accomplish multiple inheritance1 in Java using interfaces with static inner classes, which I will now present to you. First we need to define a problem that requires multiple inheritance. Let us suppose that I have a superclass, DbObject, that allows its subclasses to be loaded from and saved to the database. We also have two abstract subclasses of DbObject, ProjectADbObject and ProjectBDbObject which provide project specific functionality to all the DbObjects of each project (see class diagram). Now let's assume that both projects need a DbObject that can represent a tree structure, say Folder and Category for Project A and Project B respectively. This tree structure is represented by an interface that we will call SelfParenting. Like so:

public interface SelfParenting { SelfParenting getParent(Database db) throws DbException; }

Note that to fetch the actual instance, not just the foreign key reference, of our parent, we require the database.

So we have our two classes:

public class Folder extends ProjectADbObject implements SelfParenting { private ForeignKey parent; ... public Folder getParent(final Database db) throws DbException { return db.fetch(parent); } ... }

and

public class Category extends ProjectBDbObject implements SelfParenting { private ForeignKey parent; ... public Category getParent(final Database db) throws DbException { return db.fetch(parent); } ... }

Obviously, we're going to want more functionality than just getParent() if our interface is going to be useful. What about methods for getting the children or the depth in the tree? So we add these to our interface:

public interface SelfParenting { SelfParenting getParent(Database db) throws DbException; SelfParenting[] getChildren(Database db) throws DbException; int getDepth(Database db) throws DbException; }

And this is where we run into the multiple inheritance wall. The implementation of getChildren() and getDepth() require more than one line, and the code will be exactly the same in both Folder and Category. First, let's look at what the code might look like for the Folder class:

public class Folder extends ProjectADbObject implements SelfParenting { private ForeignKey parent; ... public Folder getParent(final Database db) throws DbException { return db.fetch(parent); }

public Folder[] getChildren(final Database db) throws DbException { final Collection children = new ArrayList(); for(final Folder folder : db.fetchAll(Folder.class)) { if(folder.getParent(db).equals(this)) children.add(folder); } return children.toArray(new Folder[0]); }

public int getDepth(final Database db) throws DbException { int depth = 0; Folder folder = this; while(folder.getParent() != null) { depth++; folder = folder.getParent(db); } return depth; } ... }

Obviously, the code will be identical in the Directory class. Is there any way to avoid this code duplication? What if we put the code into static methods of a static inner class of the interface? Like so:

public interface SelfParenting { SelfParenting getParent(Database db) throws DbException; SelfParenting[] getChildren(Database db) throws DbException; int getDepth(Database db) throws DbException;

public static class Impl { public static T[] getChildren(final Database db, final T parent) throws DbException { final Collection children = new ArrayList(); final T[] all = db.fetchAll(parent.getClass()); for(final T possibleChild : all) { if(possibleChild.getParent(db).equals(parent)) children.add(possibleChild); } return children.toArray(new T[0]); }

public static int getDepth(final Database db,
                           SelfParenting node)
  throws DbException
{
  int depth = 0;
  while(node.getParent() != null)
  {
    depth++;
    node = node.getParent(db);
  }
  return depth;
}

} }

Then, the implementation of the new methods shrink down to one line:

public class Folder extends ProjectADbObject implements SelfParenting { private ForeignKey parent; ... public Folder getParent(final Database db) throws DbException { return db.fetch(parent); }

public Folder[] getChildren(final Database db) throws DbException { return Impl.getChildren(db, this); }

public int getDepth(final Database db) throws DbException { return Impl.getDepth(db, this); } ... }

And so the proper implementation of Category will be the same:

public class Category extends ProjectBDbObject implements SelfParenting { private ForeignKey parent; ... public Category getParent(final Database db) throws DbException { return db.fetch(parent); }

public Category[] getChildren(final Database db) throws DbException { return Impl.getChildren(db, this); }

public int getDepth(final Database db) throws DbException { return Impl.getDepth(db, this); } ... }

By moving the common implementation of the getChildren() and getDepth() methods into the interface (via a static inner class), we have eliminated the duplication of code, thereby enhancing the maintainability and enabling future implementations of SelfParenting to be trivial one-line methods.

The code above is obviously very inefficient2, but it was provided to demonstrate a point: that the advantages of multiple inheritance can be achieved in java via this "static methods in a static inner class in the interface" coding pattern.

Class Diagram

Multiple Inheritance Class Diagram

1Note that this accomplishes the code reuse feature of multiple inheritance only. In theory, you could get the effects of polymorphism by doing more than, or something other than, just call the static implementation in the interface.

2A proper implementation of getChildren() would involve SQL where clauses. There are also generics issues that would cause the code, as shown, to not compile. The concept remains sound.