A class has contradicting goals
Traits
Class = object factories ⇒ need for completeness
Traits are not simply composition due the fact that the rules by which traits are made available to a class are completely different.
When using Composition, there is no chance for conflicts or methods overwriting because the composite element is a completely isolated unit (an instance of some other class) you interface with via it's public API from within the consuming instance. Also, if you need to provide access from the consuming instance, you'd have to add proxy methods to delegate to the composite element.
Traits on the other hand become part of the API of the very instance they are used in. They are not subsystems in the instance. They are not even instances but just a reusable boilerplate code.
One benefit this provides is satisfying interfaces with a trait,
(source: Are traits not simply composition? @StackOverflow)
In Class-based languages like PHP, the traits “composition” (it's merely an include on the method level of classes) happens at compile time, whereas the composition you talk about is at runtime
(source: Are traits not simply composition? @StackOverflow)
Traits are synonym of behaviour more than inheritance or decoration. It is not the same thing as strategy pattern because you can define a generic algorithme whereas each concrete strategy object has different algorithm. Moreover it is more a “horizontal” inheritance of a behaviour than a “vertical” inheritance with a specification of a behaviour.
(source: Are traits not simply composition? @StackOverflow)
Rather than replacing single inheritance, trait composition extends it using the flattening property of traits. These two operations are similar but complementary and work together nicely.
(source: Traits: Composable Units of Behaviour*, PDF)
Classes retain their primary role as generators of instances, whereas traits are purely behavioural units of reuse. Classes are organized in a single inheritance hierarchy, thus avoiding the key problems of multiple inheritance, but the incremental extensions that classes introduce to their superclasses are specified using one or more traits.
(source: Stateful Traits, PDF)
Trait composition does not subsume single inheritance. Inheritance is still needed for a class to reuse the features provided by another class. In particular, representation can only be shared by inheritance, and super only makes sense in the context of single inheritance.
(source: Classes = Traits + States + Glue, PDF)
Trait composition complements, rather than subsumes, single inheritance. Whereas inheri- tance is used to derive one class from another, traits are used to achieve structure and reusability within a class definition. We summarize this relationship with the equation
Class = Superclass + State + Traits + Glue
(source: Traits: Composable Units of Behaviour*, PDF)
In order for a class to be complete, all the requirements of the traits must be satisfied, i.e., methods with the appropriate names must be provided. These methods can be implemented in the class itself, in a direct or indirect superclass, or by another trait that is used by the class.
(source: Traits: Composable Units of Behaviour*, PDF)
Single Inheritance and the Flattening Property.
Single inheritance lets one reuse all the features (i.e., methods and state variables) that are available in a class. If a class can inherit only from a single superclass, inheriting state does not cause complications, and a simple keyword (e.g., super) is enough to access overridden methods. This mechanism for accessing inherited features is convenient, but it also gives semantics to the place of a method in the inheritance hierarchy.
Trait composition operates at a finer granularity than inheritance; it is used to modularize the behaviour defined within a class. As such, trait composition is designed to compose only behaviour and not state. In addition, trait composition enjoys the flattening property, which means that it does not assign any semantics to the place where a method is defined.
The flattening property combines with single inheritance to demonstrate that traits are a logical evolution of the single inheritance paradigm. A system based on traits naturally allows one to write and execute traditional single inheritance code. Moreover, with appropriate tool support, it also allows one to view and edit classes that are built from thousands of deeply composed traits in exactly the same way as one would if they were implemented without using traits at all.
(source: Traits: Composable Units of Behaviour*, PDF)
Since the appearance of Java, interfaces have become a popu- lar and well-accepted concept. Whereas a class can only in- herit from a single parent class, it can be made a subtype of several interfaces by implementing the specified methods. This concept has some similarities to traits, because it also in- troduces the notion of a more primitive composition that co- exists with single inheritance. However, the major difference is that traits are designed to specify reusable behavior whereas interfaces do not support any form of behavior reuse. Indeed, traits define behavior that can be reused by a set of classes not related by inheritance. Interfaces only specify a set of method signatures that classes implementing the interface must im- plement. As such, the benefit of interfaces is limited to the type system and documentation purposes.
(source: Classes = Traits + States + Glue, PDF)
You can probably think of them a bit like interfaces in Java, but instead of just defining a list of methods that need to be implemented, many of them will actually be implemented by including the module.
(source: what are some good examples of mixins or traits @stackoverflow)
If you plan to distribute it in compiled form, and you expect outside groups to write classes inheriting from it, you might lean towards using an abstract class. The issue is that when a trait gains or loses a member, any classes that inherit from it must be recompiled, even if they have not changed. If outside clients will only call into the behavior, instead of inheriting from it, then using a trait is fine.
(source: To Trait or not to Trait in Scala)
Alright. So I've got a number of 'traits' that I'm currently expressing as interfaces. Let's call them “updatable” and “destructible”. Expressing them as interfaces has the downside that I can't share behavior between all “destructible” components; on the other hand, expressing these as abstract classes mean I can't mix and match without explicitly defining the mixed trait as another abstract class (“UpdateableAndDestructible”) and furthermore this feels like an abuse of the abstract class functionality at that point. It's probably what I'll end up doing if there aren't cleaner ways of handling this, however.
(source: Ways to achive effective java traits @stackoverflow)
Most implementations of aspect-oriented programming such as AspectJ [Kiczales et al. 2001] support weaving code at more fine-grained join points such as field accesses, which is not supported by traits.
Despite the fact that traits and aspects can be used for similar purposes, there are fun- damental differences between the two approaches. By definition, aspects are concerns that cannot be cleanly encapsulated in a generalized procedure (i.e., object, method, mixin). This means that in contrast to traits, aspects are neither designed nor used to build classes and components from scratch, but rather to alter the performance or semantics of the components in systemic ways. Thus, a single aspect can be designed to modify the behavior of methods spread across the object-oriented decomposition, i.e., in many classes. A trait cannot do this.
(source: Traits: A Mechanism for Fine-grained Reuse, PDF)
The most important difference between Traits and Aspect is a matter of control: aspects control their own application to classes through pointcuts, but traits are explicitly included in classes.
(source: Metaprogramming with Traits, PDF)
With a decorator pattern it is more like delegation. If your class doesn't know how to do something, it asks its parents. In an open-class environment, a class's parents may have been modified after the class was created.
(adapted from: What are some good examples of mixins or traits @stackoverflow)
Difficulties experienced with mixins also disappear, because traits impose no composition order.
(source: Traits: A Mechanism for Fine-grained Reuse, PDF)
A Mixin adds state and inheritance chain dependency to a traits definition.
All traits are mixins, but only mixins which don’t have a state can be traits. Therefore, traits are nothing more than a subset of mixins.
(source: Are traits the new eval)
In contrast to mixins, several traits can be applied to a class in a single operation: trait composition is unordered. Instead of the trait com- position resulting implicitly from the order in which traits are composed (as is the case with mixins), it is fully under the control of the composing class.
(source: Stateful Traits, PDF)
Mixins are also collections of methods intended to be used as components of classes [6, 15]. The major difference between mix- ins and traits is that whereas mixins must be applied to classes one at a time using the inheritance operation, traits are subject to a richer set of composition operators, giving the programmer more freedom in the way that they can be combined.
(source: Traits: A Mechanism for Fine-grained Reuse, PDF)
Traits bear a superficial resemblance to mixins, with several important differences. Several traits can be applied to a class in a single operation, whereas mixins must be applied incrementally. Trait composition is unordered, thus avoiding problems due to linearization of mixins. Traits contain only methods, so state conflicts are avoided, but method conflicts may exist. A class is specified by composing a superclass with a set of traits and some glue methods. Glue methods are defined in the class and they connect the traits together; i.e., they implement required trait methods (possibly by accessing state), they adapt provided trait methods, and they resolve method conflicts.
(source: Traits: A Mechanism for Fine-grained Reuse, PDF)
The notion of parametric heir classes or mixins avoids many of the complications caused by multiple inheritance, but it still allows more flexible class hierarchies and better code re- use than traditional single inheritance. As the first name sug- gests, a mixin is an abstract subclass; i.e., a subclass definition that maybe applied to different parent classes to create a relat- ed family of modified classes [5]. As the first name suggests, a mixin is a uniform extension of many different parent class-es with the same set of fields and methods. As such, the con- cept of mixins allows the programmer to achieve better code reuse without sacrificing the simplicity of linear inheritance chains. Mixins are used in languages such as Ruby [19] and Smallscript [15] and there exist several extensions of Java [3] or Smalltalk with mixins.
The main differences between mixins and traits are two- fold. First, mixins are just a more general form of classes, which means that they usually include state in the same way classes do and that there is often no explicit notion of required and provided services (Jam is an exception [3]). Second, the extension of a class with a mixin always results in a new class, and in the same way, composition of two mixins yields anoth- er one. This avoids the problems caused by multiple inherit- ance paths, but it also leads to the following problems:
As an example, assume that we would like to use a tradi- tional mixin implementation (such as Jam [3]) to write a class that provides the behaviour corresponding to the mixins Cir- cle, Color, Visual, and Serializable. In order to do that, we have to define a particular order such as Circle → Color → Visual → Serializable, create explicit entities ColoredCir- cle, VisualColoredCircle, SerializableVisualColored- Circle, and spread the necessary glue code among all of them.
(source: Classes = Traits + States + Glue, PDF)
Difficulties experienced with multiple inheritance disappear with traits, because traits are divorced from the inheritance hierarchy.
(source: Traits: A Mechanism for Fine-grained Reuse, PDF)
At a first glance, trait composition is very similar to multi- ple inheritance. Both approaches allow one to reuse function- ality from more than one source at the same time, which has the benefit of better code reuse and allows more flexible class hierarchies. Nevertheless, there are essential differences:
Reuse of traits vs. reuse of classes.
Multiple inheritance al- lows functionality to be reused from multiple classes which generally implement an already specialized version of a cer- tain behaviour and also include state. This means that the no- tion of a class is used in two very different ways: On one hand, classes are used to represent already specialized entities that can be instantiated, and at the same time, they represent the most primitive entities of code reuse. With trait composition, these two roles are completely separated and are provided by two different entities. Traits are the primitive entities of code reuse and the majority of the code is implemented in such traits. Their structure is simpler than the one of classes (e.g. no state), which enforces the programmer to write the behaviour in a very general and reusable way. In contrast to traits, classes represent more concrete and specialized functionalities, which typically consist of different aspects that are realized by using appropriate traits and specifying the necessary glue code.
Diamond problem.
One of the most troublesome aspects of multiple inheritance is the “diamond problem”, which occurs when a class inherits state from the same base class via multiple paths. With traits, we sidestep this problem because traits do not define any state.
Traits do not replace single inheritance.
Both traits and multiple inheritance are an extension of traditional single inheritance. However, whereas multiple inheritance replaces single inheritance, traits are an orthogonal concept that coex- ists with single inheritance. This means that a language with traits still provides all the well-accepted features and benefits of single inheritance: A class can be derived from (at most) one parent class, it can inherit state from (at most) one parent class, and it can explicitly call inherited services in an unam- biguous manner.
Simplicity.
Many multiple inheritance implementations pro- vide powerful and sophisticated features to resolve and avoid method conflicts. CLOS, for example, allows a programmer to freely define how the inheritance graph is linearized. Eiffel allows explicitly renaming or deleting of inherited methods in order avoid method conflicts, and C++ supports explicit call- ing of an arbitrary inherited method from within the code of another method. In contrast to that, our trait model has been developed with the main goal of simplicity and clarity. This makes our approach less flexible, but it also enforces cleaner designs and ensures that the resulting code is better under- standable.
(source: Classes = Traits + States + Glue, PDF)