Since the dawn of object-oriented programming, a fundamental problem has plagued OO language design. On one hand, the ontologies we develop during domain analysis tend to involve classes that inherit from multiple parents. That's because objects in the real world just don't fit into a simple single inheritance hierarchy. Your favorite beer may both taste great and be less filling. On the other hand, allowing for multiple inheritance in a programming language results in tremendous semantic complexity.
Introducing so much complexity into a language tends to increase the occurrences of bugs, so the Java language has taken the approach of sticking to single inheritance (except for interface inheritance, where the semantics are much more straightforward). As a result, many class structures in Java programs include either copied code along multiple branches of the inheritance hierarchy or added levels of indirection using the Chain of Responsibility, Command, or Strategy design patterns.
For example, consider the following example of a UML analysis diagram for scrollable panes for a GUI library:
Figure 1. An analysis diagram for select GUI elements

Ideally, we would like to translate this diagram directly into a class hierarchy in Java programming. However, because of single inheritance, we can't. Granted, multiple interface inheritance would allow us to construct a corresponding set of interfaces, but the classes implementing these interfaces couldn't follow the structure directly. Instead, we'd either have to copy code along multiple paths in the inheritance hierarchy or employ the Strategy pattern (or some other trick using containment) to avoid copying code. Neither approach is entirely satisfactory.
Getting the best of both worlds
But if multiple inheritance is too error-prone, and single inheritance is too limiting, is there any language feature we could add to Java programming that would provide us with the best of both worlds? It turns out that there is -- it's known as a mixin.
Mixins are classes that are parameterized by their parent class. They can also be thought of as functions mapping classes to new subclasses. Mixins can be instantiated with different parent classes depending on the requirements of a particular context.
For example, the class hierarchy for ScrollPane in Figure 1 could be implemented using mixins as follows (where the directed dashed lines represent instantiation relations from mixins to parent classes):
Figure 2. A mixin inheritance diagram

In Figure 2, we've turned class Scrollable into a mixin that can extend different classes in different contexts. In this context, we instantiate Scrollable to extend Pane, to create a ScrollPane. We could also instantiate Scrollable to extend Dialog, and we could instantiate it to extend all sorts of other GUI components as necessary in various contexts.
The first use of the word mixin originated with the Lisp community. It was employed in the mainstream in CLOS where it was actually a design pattern to try to control the unwieldiness of the multiple inheritance of that language. A mixin design pattern had also been applied by the C++ community for the same purpose.
The name mixin was used because such classes can be mixed together with other classes in various ways. Although mixins are simply a design pattern in these languages, there's no reason why they can't be supported at the language level. Many proposals have been made to add mixins to the Java language, but the most popular proposal so far is Jam, an extension of Java with mixins from Italian researchers Davide Ancona, Giovanni Lagorio, and Elena Zucca.
Mixins, Java code, and Jam: Not just for breakfast
Jam is a backward-compatible extension of the Java platform, v1.0 (with two new keywords: mixin and inherited). Admittedly, unless you're writing Java programs to .NET, you would be using a pretty old version of the language, but the fundamental design could be extended to more modern versions.
An implementation is provided as a Jam-to-Java language translator. Note that the jamc implementation does not perform a complete type check of a program. Instead, it translates to Java source and relies on the Java type checker to catch type errors. This makes the Jam implementation simpler, but it also means that it will be more difficult to diagnose error messages we get back from the compiler because they will be one step removed from the source code we actually wrote! In the long run, a stand-alone Jam type checker would be essential for production use.
In Jam, the methods required in the parent class are declared with declarations inside the mixin class def, like this: inherited <signature>.
Instantiations of a mixin are written like this: class NAME = MIXIN extends CLASS {CONSTRUCTOR*}
.
The * at the end of the CONSTRUCTOR production signifies that there can be zero or more occurrences of that production. If no constructors are specified in a mixin instantiation, the default zero-argument (zeroary) constructor is assumed.
For example, the mixins employed in the UML diagram (Figure 2) could be written as follows (in which we include the method setVisible() on Panes, and a maxScrollSize field in mixin Scrollable):
class Pane {
...
void setVisible(boolean value) {
...
}
}
class DialogBox {
...
}
mixin Scrollable {
int maxScrollSize;
inherited void setVisible(boolean value);
}
class ScrollDialog = Scrollable extends DialogBox {
ScrollDialog() {
this.maxScrollSize = 10;
}
}
class ScrollPane = Scrollable extends Pane {
ScrollPane(int maxScrollSize) {
this.maxScrollSize = maxScrollSize;
}
}
|
Jam obeys what is known as the "copy principle for mixins":
A class obtained by instantiating a mixin M on a parent class P should have the same behavior as a usual heir of P whose body contains a copy of all the components defined in M.
Although the concept of mixins has been applied to many languages, Jam is novel in that it introduces mixin-based programming rigorously in the context of a strongly typed language. Mixins in Jam, like ordinary classes, define types; mixin instantiations have both the type of the mixin and the type of the parent. A mixin can implement multiple interfaces.
Constructors cannot be declared in a mixin, but only for mixin instantiations. As the designers of Jam state, constructors were not allowed as a design choice because they are "tightly tied up with the implementation of their own class, so their signatures tend to not be very general."
Some general properties to note about this language:
- Field members are accessible through the same rules as with the standard Java language.
- Static members are associated with instantiations of mixins; there are no "shared" static members of mixins.
Additionally, Jam imposes five constraints on the instantiation of a mixin:
- Illegal overriding/hiding. Accidental (a.k.a., "incidental") overriding of a method from a parent class is allowed if the corresponding "copied" class is legal (that is, a method would not have the same arg type, but a different return type as an overridden method in the parent class, or a different throws clause, or incompatible modifiers, such as static versus instance).
- Ambiguous overloading. Ambiguous overloading is a problem because method arguments may be of mixin type, allowing for situations in which two overloaded methods are applicable and neither is more specific. This problem is solved by disallowing overloading if the two methods have the same number and type of arguments except for some argument for which they have two different reference types.
- Method annotation. Inherited methods are annotated with "Parent" type.
- Class-only instantiation. Jam mixins can be instantiated only on classes; unlike components in Jiazzi, there is no notion of mixin composition (however, the Jam team would like to explore such an extension). For more on Jiazzi and component-based programming, see Resources.
- No "this" passing. A potential show-stopper, passing "this" as an argument to a method or a constructor from inside a mixin is forbidden! This Jam idiosyncrasy is necessary to preserve the soundness of the type system. Without it, there is no way to ensure that a Jam mixin type will be valid across all possible instantiations. Nevertheless, it's a very unfortunate restriction because it limits the set of classes eligible to be turned into mixins.
Under the hood: A brief peek at the implementation
To translate to the Java language, Jam mixin types are represented as interfaces, implemented by the instantiations (all of which are known statically). To handle fields introduced in mixins, getter/setter methods are introduced in the interface: M_$get$_f and M_$set$_f. Then f is declared as a field in every instantiation and the methods are implemented appropriately (also, all field accesses on expressions of static type M that are from external code are converted to calls to the getter/setter). Static fields in mixins are not shared across mixin instantiations and are therefore simply inserted separately in each instantiation.
Each instantiation of a mixin is compiled to a separate Java class; no sharing of bytecode occurs across copies. An interface is also constructed for the parent of the mixin. This parent interface is extended by the mixin interface (but not by the instantiations of the parent class).
Mixins are generally motivating to programmers as a way to get back the power of multiple inheritance in a language without all the pitfalls. But it's important to note that they also provide us with a powerful way to test new extensions of existing classes, particularly when the nature of a parent class is such that direct testing of it is difficult (as in a GUI element or an RMI proxy class).
In fact, just as Jiazzi provides us with a way to test packages independently of the packages they import, Jam (or any other mixin-based extension of the Java language) allows us to test classes independently of their parents, even if those parents exist in the same package. Following our example in Listing 3, we could instantiate our mixin with a Recorder for a parent class that simply logged all invocations of super methods:
class TestLog {
private StringBuffer recording = new StringBuffer("");
public void record(String message) {
recording.append(message);
}
public String toString() {
return recording.toString();
}
}
class WidgetRecorder {
public TestLog testLog;
public void setVisible(boolean value) {
testLog.record("setVisible(" + value + "); ");
}
}
class ScrollableWidgetRecorder = Scrollable extends WidgetRecorder {
public TestScrollable() {
this.maxScrollSize = 10;
}
}
|
We could then check this log against an expected sequence of invocations:
import junit.framework.*;
public class ScrollableTest extends TestCase {
public ScrollableTest(String name) {super(name);}
public void testSetVisible() {
ScrollableWidgetRecorder test = new ScrollableWidgetRecorder();
test.initialize();
assertEquals("Scrollable initialization should've called setVisible(true)",
"setVisible(true); ",
test.testLog.toString())
}
...
}
|
In this way, we would be able to test extensions of classes that were themselves difficult to test, regardless of the location of the parent classes. Core functionality that's difficult to test could then be isolated into a small set of parent classes, while the functionality that relies on it can rest in thoroughly tested mixin classes.
A final word on mixins and generic types
Finally, I would be remiss in discussing mixins in Java programming without at least briefly discussing how mixins relate to the JSR-14 proposal to add generic types to Java.
Because generic types allow classes to be parameterized by the types to which they refer, true first-class support for generic types in the Java language would necessarily have to support a form of mixins, because a class could be defined to extend a type variable.
Unfortunately, the approach used by Sun's JSR-14 prototype compiler prohibits such a "first-class" extension because generic types are erased during static compilation; no generic type information even exists at run time. In the case of mixins, this would mean that the parent class of a mixin would be erased to the bound of the type variable which is clearly not what we would want.
In contrast, the NextGen formulation of generic types (due for beta release from Rice JavaPLT in December 2002) keeps generic type information available at run time. It could therefore be extended to support first-class generic types, including mixins. Indeed, an extension soon after the first beta release should include just such functionality. A design of the extended language is available in Resources.
As this article and the previous one demonstrated, the Java language as it exists today is not the last word in language design, especially when we employ the style of test-first programming. There are many powerful and natural language extensions that can allow us to test our programs more quickly and thoroughly.
Hopefully, though, these two articles have also shown the tremendous flexibility and extensibility that the Java language allows. This extensibility is a direct result of the safety and portability of the language and JVM designs. Because of the foresight of the original designers, the Java language will prove to remain a very powerful and relevant language for a long time to come, continuing to serve programmers while they build increasingly complex applications.
- Eric Allen has a new book on the subject of bug patterns, a notion first introduced in this column: Bug Patterns in Java (Apress, 2002).
- Get a quick look into the Jam language, an extension of the Java language that supports mixins, and download it.
- This extended abstract (PDF file) from Rice JavaPLT explains how Java can be extended with true first-class generic types in a manner fully compatible with existing compiled binaries.
- See this earlier Diagnosing Java code article, "Recorders test for proper method invocation" (developerWorks, June 2001), to learn about using Recorders for enhanced unit testing.
- November's Diagnosing Java code article, "Decoupling package dependencies," covers Jiazzi and writing component-based code for better testability.
- Learn more about generic types in the author's JavaWorld article, "Behold the power of parametric polymorphism" (February 2000).
- Examine seven principles to build a base for code design with testing in mind in "Diagnosing Java code: Designing 'testable' applications" (developerWorks, September 2001).
- Explore the complete archives of Diagnosing Java code for technical nuggets ranging from bug patterns to testability to design strategies.
- Follow the discussion of adding generic types to the Java language by reading the Java Community Process proposal, JSR-14.
- "Catching more errors at compile time with Generic Java ," by Keith Turner (developerWorks, March 2001), offers a look at how Generic Java provides an elegant way to implement generic utility classes that alleviates the need to cast and allows more errors to be caught at compile time.
- "Automatic Code Generation from Design Patterns" (PDF file), from IBM Research, describes the architecture and implementation of a tool that automates the implementation of design patterns.
- Find hundreds more Java technology articles and tutorials on the developerWorks Java technology zone.
Eric Allen sports a broad range of hands-on knowledge of technology and the computer industry. Starting with a B.S. in computer science and mathematics from Cornell University and an M.S. in computer science from Rice University (culminating in proven experience as the lead Java developer at Cycorp), Eric is currently a Ph.D. candidate in the Java programming languages team at Rice. Under the advisement of Dr. Robert "Corky" Cartwright, Eric's research concerns the development of semantic models and static analysis tools for the Java language at the source and bytecode levels. He is also concerned with the verification of security protocols through semantic formalisms and type checking.
Eric is a project manager for and a founding member of the DrJava project, an open-source Java IDE designed for beginners; he is also the lead developer of the university's experimental compiler for the NextGen programming language, an extension of the Java language with added experimental features. Eric has moderated several Java forums for the online magazine JavaWorld. In his spare time, he teaches software engineering to Rice University's computer science undergraduates. Contact Eric at eallen@cs.rice.edu.




