23

On page 93-4 of Effective Java, I came across the term mixin. But I am finding it difficult to visualise what a mixin actually is. Could anybody please help me out by providing an example of a mixin in Java?

Laurel
  • 5,965
  • 14
  • 31
  • 57
blackpanther
  • 10,998
  • 11
  • 48
  • 78

3 Answers3

27

You're referring to Item 18 of Effective Java - Prefer interfaces to abstract classes, and I believe the following section in particular:

Interfaces are ideal for defining mixins. Loosely speaking, a mixin is a type that a class can implement in addition to its "primary type" to declare that it provides some optional behaviour. For exampleComparable is a mixin interface that allows a class to declare that it its instances are ordered with respect to other mutually comparable objects. Such an interface is called mixin because it allows the optional functionality to be "mixed in" to the type's primary functionality. Abstract classes can't be used to define mixins for the same reason that they can't be be retrofitted onto existing classes: a class cannot have more than one parent, and there is no reasonable place in the class hierarchy to insert a mixin.

Essentially, one of the key differences between specifying functionality in an abstract class and in an interface is that the interface version can be used in a number of different class hierarchies, whereas an abstract class can only be used in the one class hierarchy tree because Java only allows single-inheritance.

Edd
  • 3,724
  • 3
  • 26
  • 33
  • 2
    It's useful to compare this definition to a mixin in another language like Ruby or Python. In those languages, classes can have multiple parents, and so it is possible for a class to bring in logic from an arbitrary number of generic parents. They are considered mixins because rather than being considered the primary parent of a class, they are some additional logic that has been "mixed in." Example: http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html#S2 – Brandon Yarbrough Aug 01 '13 at 08:14
  • 19
    Interfaces are not mix-ins. Interface doesn't hold state or even code, therefore it's not a mix-in. For instance you cannot define a mix-in called `Traversable` with one abstract method `forEach` and 10 concrete methods that provide functionality based on it (`drop`, `take`, `filter`, `map`,...).With interfaces you can declare all these methods, but any class implementing this interface will have to provide implementation for all of them instead of just 1.Abstract classes work great for this, but they are limited to just 1 as parent of a class and they put you in specific hierarchies.Not mixin – RokL Aug 01 '13 at 09:00
  • 1
    @RokL I assume this comment is before the release of Java 8, after which you could do *exactly* that, using default methods? ;) – Haakon Løtveit Apr 04 '22 at 08:09
  • @HaakonLøtveit No you cannot, your default method on an interface can only operate on arguments, you still cannot add fields to an object via Interface, which is what mix-in class does in Scala for instance. – RokL Apr 06 '22 at 10:27
  • 1
    @RokL But we're talking about Effective Java, and what the word is used for there. You definitively CAN do things like that using default interfaces. You can easily write an interface with default String toJson() that did exactly as you'd expect. – Haakon Løtveit Apr 07 '22 at 07:54
11

There is no such thing as mix-in in java since there's no way to add the a piece of code to classes in separate hierarchies. To do so would require multiple inheritance or a least Scala type traits.

RokL
  • 2,663
  • 3
  • 22
  • 26
  • 1
    Aspects are not part of Java language. Aspects in java are implemented by byte-code weaving after the code is complied, so it's an after-compile tool. – RokL Aug 01 '13 at 08:05
  • But java enables such byte-code weaving. And interface-proxies are a part of Java. – Web Devie Aug 01 '13 at 08:23
  • 1
    Interface proxies do not provide a full mix-in support. – RokL Aug 01 '13 at 08:52
4

In 'Effective Java'`s scope, it is mentioned just logically, without specific Java implementation. For example, a Comparable interface. It doesn't change your class purpose or confuse your api users. It just mixes in functionality for sorting and comparation. So, in a Java context I would narrow this to a Decorator pattern.

Another variation on a mix-in could be the following. Assume, you have:

interface IMyInterface
{
    public void doStuff();
}

class MyClass implements IMyInterface
{
    public void doStuff(){};
}

Now we want to 'mix in' some additional functionality. We add an abstract class:

abstract class AbstractMixInProvider
{
    public abstract void doMixinStuff();
}

And we extend MyClass from AbstractMixInProvider:

class MyClass extends AbstractMixInProvider implements IMyInterface
{
    public void doStuff(){};
    public void doMixinStuff();
}

But, as I`ve mentioned above, trying to pull mix-in concept to Java looks ugly, because it is just play on words.

Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
Michael Cheremuhin
  • 1,381
  • 11
  • 17
  • The example is for only one interface, which is no mixin – Web Devie Aug 01 '13 at 08:24
  • In this example I`ve used AbstractMixInProvider as a mixin. It is not the point if it is an interface or not. I tried to discribe a sample situation for @blackpanther, so he could understand the approach from 'Effective Java'. – Michael Cheremuhin Aug 01 '13 at 08:27
  • You can't do this with 2 abstract classes this way. – Web Devie Aug 01 '13 at 08:34
  • No, you can`t. That why you can use multiple interfaces for your target class or one AbstractMixinProvider with multiple interfaces in it. That`s why I think, that calling all this stuff 'mixin' is weird. – Michael Cheremuhin Aug 01 '13 at 08:38