Geek Culture
Published in

Geek Culture

Mixin and traits

Mixin, the Diamond problem, inheritance

Mixins are synonymous with abstract base classes. Inheriting from a mixin is not a form of specialization but is rather a means of collecting functionality. A class or object may “inherit” most or all of its functionality from one or more mixins, therefore mixins can be thought of as a mechanism of multiple inheritance…

…Mixins encourage code reuse and avoid well-known pathologies associated with multiple inheritance. However, mixins introduce their own set of compromises…

…When a class includes a mixin, the class…includes, rather than inherits, all the mixin’s attributes (fields, properties) and methods. They become part of the class during compilation.

With mixins the class definition defines only the attributes and parameters associated with that class; methods are left to be defined elsewhere, as in Flavors and CLOS, and are organized in “generic functions”. These generic functions are functions that are defined in multiple cases (methods) by type dispatch and method combinations.

CLOS and Flavors allows mixin methods to add behavior to existing methods: :before and :after daemons, whoppers and wrappers in Flavors. CLOS added :around methods and the ability to call shadowed methods via CALL-NEXT-METHOD. So, for example, a stream-lock-mixin can add locking around existing methods of a stream class. In Flavors one would write a wrapper or a whopper and in CLOS one would use an :around method. Both CLOS and Flavors allow the computed reuse via method combinations. :before, :after and :around methods are a feature of the standard method combination. Other method combinations are provided.

…Some languages like ECMAScript (commonly referred to as JavaScript) do not support mixins on the language level, but can easily mimic them by copying methods from one object to another at runtime, thereby “borrowing” the mixin’s methods. Note that this is also possible with statically typed languages, but it requires constructing a new object with the extended set of methods…

…Some of the functionality of mixins is provided by interfaces in popular languages like Java and C#. However, an interface only specifies what the class must support and cannot provide an implementation. Another class, providing an implementation and dependent with the interface, is needed for refactoring common behavior into a single place.

Interfaces combined with aspect-oriented programming can produce full fledged mixins in languages that support such features, such as C# or Java. Additionally, through the use of the marker interface pattern, generic programming, and extension methods, C# 3.0 has the ability to mimic mixins.

http://en.wikipedia.org/wiki/Mixin

A little sample in Scala Language, based on http://c2.com/cgi/wiki?MixIn:

And

new ColoredPoint3D(1, 2, 3, "blue").toString()

will return

"x = 1, y = 2, z = 3, col = blue".

Mixin can be viewed as partial realization of multiple inheritance. In the programming languages that supports multiple inheritance, mixin can be easily emulated. For example, in C++ template can be used for adding operator given operator «==» (based on http://ru.wikipedia.org/wiki/Примесь_(программирование):

The inheritance mechanism is a core component of the Object Oriented Programming paradigm. Inheritance means that a class “inherits” another class’s definition and type. Inheritance express IS-A relationship. A dog IS-A pet, a car IS-A vehicle.

I want to emphases it again: code-reuse is not a goal for inheritance. Code-reuse is a goal of mixin (see below). In Python mixin implemented by using of (cooperative multiple) inheritance (see below).

The “diamond problem” is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C. If there is a method in A that B and C have overridden, and D does not override it, then which version of the method does D inherit: that of B, or that of C?

https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem

It is called the “diamond problem” because of the shape of the class inheritance diagram in this situation. In this case, class A is at the top, both B and C separately beneath it, and D joins the two together at the bottom to form a diamond shape.

Mixin Wikipedia defines a mixin as “a class that provides a certain functionality to be inherited by a subclass, but is not meant to stand alone. Inheriting from a mixin is not a form of specialization but is rather a means to collect functionality. A subclass may even choose to inherit most or all of its functionality by inheriting from one or more mixins through multiple inheritance. A mixin can also be viewed as an interface with implemented methods.

Inheritance defines an “is a” relationship between classes. A dog is ‘is a’ pet, a car “is a” vehicle — a car is a specialization of a vehicle. A mixin, on the otherhand, is a means of sharing functionality among a series of related classes that do not inherit from the same base class. A mixin allows you to reuse code without implying a relationship among the classes. It also allows you to get around the Single Inheritance model a bit to do this.

I’m starting with JavaScript example, because its implement mixin by actually copying methods from mixin to object, that is good mental model for that mixin is.

All other examples (with exception of C#) use inheritance to implement mixin that is theoretically wrong, because mixin don’t have IS-A semantic.

Mixin in JavaScript

Based on https://en.wikipedia.org/wiki/Mixin#In_JavaScript

It is technically possible to add behavior to an object by binding functions to keys in the object. However, this lack of separation between state and behavior.

First way — using extend(obj, mixin) function.

Second way — Object.assign(obj, mixin)

Java with version below 8

Pre Java-8 Java Object’s doesn’t have multiple inheritance. The standard way to simulate multiple inheritance in Java is delegation / composition / decorator.

Delegation:

Decorator:

The ultimate example of such technique is BufferedOutputStream. Ability to buffer stream modeled in Java as Object (because “‘everything’ in Java is object”). Actually, it should be mixin. This is orthogonal concept. For example, this ability is also used in BufferedInputStream.

Note:

Pre Java-8 has multiple inheritance with interfaces. Class can implements multiple interfaces (interface can also extends another interfaces). The ambiguity that raise with method name collision is very limited. Anyway, the collision is between two (or more) purely abstract method. Provided, that interface has no state, it doesn’t really matter which method wins (in order to the class to be usable, you should provided implemetaion of such method in the class anyway, and such implementation will be used for all purely abstract methods). In particular, if we have diamond problem, the problem is with purely abstract methods, so the issue is very limited as described above.

Java 8 interface

has limited support for multiple inheritance in interfaces. You can have actual behavior there (by default (non-abstract) methods; also you can hive static methods, but this has nothing to do with inheritance), but you can’t have state there (no data-members allowed). So, while technically you have diamond problem, the method resolution rules was specifically crafted in such a way that there is no ambiguate on which class to call. State appears only when you have class that implemented these interfaces. If he provides his own implementation, it’s implementation wins, if didn’t, implementation of one the interfaces will be used (Java doesn’t take in consideration the order of the specified interfaces in the implements clause), but since interface don’t have the state, it doesn’t matter which particular interface will be used.

Note: Java 8 interfaces are still stateless.

With the introduction of default methods in Java 8, it is now possible for a class to inherit the same method from multiple places (such as another class or interface). The following rules can be used to determine which method is selected in such cases:

1. A class or superclass method declaration always takes priority over a default method
2. Otherwise, the method with the most specific default-providing interface is used
3. Finally, if the methods are equally specific, there will be a compiler error and you will be forced to explicitly override the method and specify which one your class should call

Answer: A

The sub-interfaces B and C haven’t overridden the method, so there is actually only the method from A to choose from. As a side note, if either B or C (but not both) had overridden the method, then Rule 2 would have applied. By the way, this is the diamond problem.

https://fahdshariff.blogspot.com/2016/06/java-8-default-method-resolution-rules.html

If rule 1 and rule 2 fail to determine which method to use, than by rule 3 we should add method in the class that implements there interfaces, that will provide explicit call to one of the interfaces. See the link above for the detail explanation and examples of these rules.

Scala

Based on https://en.wikipedia.org/wiki/Mixin#In_JavaScript

…As their name reveals, Traits are usually used to represent a distinct feature or aspect that is normally orthogonal to the responsibility of a concrete type or at least of a certain instance. For example, the ability to sing is modeled as such an orthogonal feature: it could be applied to Birds, Persons, etc.

Note: Scala’s trait can have state. Scala support multiple inheritance of traits. There are stricked rule on how multiple inheritance is resolved. Java 8 interfaces are traits.

Here, Bird has mixed in all methods of the trait into its own definition as if class Bird had defined method sing() on its own.

As extends is also used to inherit from a super class, in case of a trait extends is used if no super class is inherited and only for mixin in the first trait. All following traits are mixed in using keyword with.

C# 3.0

can also simulate mixin by using extension method, see Implementing Mixins with C# Extension Methods.

Kotlin

can simulate mixin in both way, as Java 8 interfaces and as extension methods.

Python

Based on https://en.wikipedia.org/wiki/Mixin#In_Python

In Python mixin implemented by using of inheritance.

In Python, the SocketServer module has both a UDPServer class and a TCPServer class. They act as servers for UDP and TCP socket servers, respectively. Additionally, there are two mixin classes: ForkingMixIn and ThreadingMixIn. Normally, all new connections are handled within the same process. By extending TCPServer with the ThreadingMixIn as follows:

the ThreadingMixIn class adds functionality to the TCP server such that each new connection creates a new thread. Alternatively, using the ForkingMixIn would cause the process to be forked for each new connection. Clearly, the functionality to create a new thread or fork a process is not terribly useful as a stand-alone class.

In this usage example, the mixins provide alternative underlying functionality without affecting the functionality as a socket server.

--

--

--

A new tech publication by Start it up (https://medium.com/swlh).

Recommended from Medium

(JAVA) Software development: What tool can I use if I want to implement SMS sending or software…

What I’ve Learned After One Month of Doing Leetcode / HackerRank Problems

Behaviour Driven Development(BDD) in Test Automation

AWS — Helping split the cost of the Cloud

Flipside’s Chainwalkers and The Redshift COPY Command

Developing Complete Authorization Modules with AWS Lambda & Go & PostgreSQL & Event-Driven SQS…

PUZL Punks: 🧩 Expansion Packs

Introducing GitPOAP

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
alex_ber

alex_ber

Senior Software Engineer at Pursway

More from Medium

Java as a first programming language?

Longest Repeating Character Replacement

The Reference Trap

Strings in Java, Why are they special?