Jon Aquino's Mental Garden

Engineering beautiful software jon aquino labs | personal blog

Thursday, July 28, 2005

The Java Mixin Pattern, or Faking Multiple Inheritance

Unlike C++, Java supports single inheritance only -- it does not support multiple inheritance. Same with Ruby -- but Ruby has the concept of "Mixins", which are "partial classes" that you can bolt onto your class, giving you something very like multiple inheritance.

You can fake mixins in Java. They're great when you want to refactor common functionality from two classes having different superclasses. Just make a new class called FooMixin to hold the common functionality -- the magic of inner classes handles the rest. Here's a real-world example from the OpenJUMP open-source GIS project:

public class LoadDatasetFromFilePlugIn extends AbstractLoadDatasetPlugIn {
protected void setSelectedFormat(String format) {
loadSaveDatasetFileMixin.setSelectedFormat(format);
}
protected String getSelectedFormat() {
return loadSaveDatasetFileMixin.getSelectedFormat();
}
protected Collection showDialog(WorkbenchContext context) {
final JFileChooser fileChooser = GUIUtil
.createJFileChooserWithExistenceChecking();
fileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
fileChooser.setMultiSelectionEnabled(true);
return loadSaveDatasetFileMixin.showDialog(fileChooser,
LoadFileDataSourceQueryChooser.class, context);
}
private LoadSaveDatasetFileMixin loadSaveDatasetFileMixin = new LoadSaveDatasetFileMixin() {
protected String getName() {
return LoadDatasetFromFilePlugIn.this.getName();
}
protected String getLastDirectoryKey() {
return LoadDatasetFromFilePlugIn.this.getLastDirectoryKey();
}
public boolean isAddingExtensionIfRequested() { return false; }
public File initiallySelectedFile(File currentDirectory) { return null; }
};
}
Note that the LoadSaveDatasetFileMixin has access to the main class (via template methods like #getName, #getLastDirectoryKey), and the main class of course has access to the mixin (via #setSelectedFormat, #getSelectedFormat). Beautiful.

15 Comments:

  • Check out the classic Effective Java from Joshua Bloch for more about that. Item 16 ...

    By Anonymous Anonymous, at 7/29/2005 1:47 p.m.  

  • Hi Manfred - Hm! Interesting to see the idea of mixins mentioned in print.

    By Blogger Jonathan, at 7/29/2005 1:54 p.m.  

  • Nice photos.

    By Anonymous Anonymous, at 8/04/2005 2:55 a.m.  

  • Thanks FF!

    By Blogger Jonathan, at 8/04/2005 7:53 p.m.  

  • While a useful patterns, It's still not a true mixin as I would like, as you still have to have the signatures of the 'parents' added to the child class, and proxied to them, which depending on your intension of maintenance can be a good thing or a bad thing. If you have lots of children or lots of parents in flux this can get quite tedious. I suppose you can use runtime reflection to build a 'real' mixin, but I'm sure there's performance overhead on that way.

    By Anonymous Anonymous, at 10/11/2005 2:49 p.m.  

  • everytime i read sometime like this it reminds me that java are too verbose...

    how come people program in it?

    By Anonymous Anonymous, at 10/29/2005 11:02 a.m.  

  • Yeah, there are languages that are a lot more fun than Java. Then again, there are languages that are a lot less fun than Java as well :-)

    By Blogger Jonathan, at 10/29/2005 11:05 a.m.  

  • Another way is using dynaop (https://dynaop.dev.java.net/nonav/release/1.0-beta/manual/ch02s02.html).

    Christian

    By Blogger Christian Ullenboom, at 7/23/2007 11:26 a.m.  

  • Thanks Christian - I'll need to check out dynaop.

    By Blogger Jonathan, at 7/23/2007 11:26 p.m.  

  • hey jonathon, just got back from job interview asking this exact question - i wish i'd read it beforehand. nice post, i'll know how to do it next time :)

    By Anonymous Anonymous, at 2/07/2008 5:39 a.m.  

  • Hi Anon - Ah, interesting.

    Hope the job hunt is going well.

    By Blogger Jonathan, at 2/07/2008 9:45 p.m.  

  • Grr - code is obscured by the pictures in Firefox at my laptop's screen size. Good job this is about programming, not web design!

    By Blogger digitig, at 5/19/2008 11:36 a.m.  

  • True mixins are in badly need by business applications. Unfortunately any approach I know has its own disadvantages. AOP is tricky. Delegating is copy-paste approach which suffers from non-inherited annotations and so on.

    From the other hand it is not so difficult to implement mixins in Java compiler. With mixins there isn't collisions like multiple inheritance brought in C++. I think people that decide not to implement mixins in Java 7 are too far from understanding what are the benifits of mixins.

    By Blogger Vladimir Kovalyuk, at 10/21/2008 7:47 a.m.  

  • i could hardly call that beautiful, but i guess it is the closest you can get to MI in pure java code.

    By Anonymous Anonymous, at 12/02/2010 8:43 a.m.  

  • @Anonymous - Yeah, perhaps beautiful isn't the right word to describe this code :-)

    By Blogger Jonathan, at 7/21/2011 8:02 p.m.  

Post a Comment

<< Home