Trait (computer programming). In computer programming, a trait is a language concept that represents a set of methods that can be used to extend the functionality of a class.

Rationale
In object-oriented programming, behavior is sometimes shared between classes which are not related to each other. For example, many unrelated classes may have methods to serialize objects to JSON. Historically, there have been several approaches to solve this without duplicating the code in every class needing the behavior. Other approaches include multiple inheritance and mixins, but these have drawbacks: the behavior of the code may unexpectedly change if the order in which the mixins are applied is altered, or if new methods are added to the parent classes or mixins.

Traits solve these problems by allowing classes to use the trait and get the desired behavior. If a class uses more than one trait, the order in which the traits are used does not matter. The methods provided by the traits have direct access to the data of the class.

Characteristics
Traits combine aspects of protocols (interfaces) and mixins. Like an interface, a trait defines one or more method signatures, of which implementing classes must provide implementations. Like a mixin, a trait provides additional behavior for the implementing class.

In case of a naming collision between methods provided by different traits, the programmer must explicitly disambiguate which one of those methods will be used in the class; thus manually solving the diamond problem of multiple inheritance. This is different from other composition methods in object-oriented programming, where conflicting names are automatically resolved by scoping rules.

Operations which can be performed with traits include:
 symmetric sum: an operation that merges two disjoint traits to create a new trait
 override (or asymmetric sum): an operation that forms a new trait by adding methods to an existing trait, possibly overriding some of its methods
 alias: an operation that creates a new trait by adding a new name for an existing method
 exclusion: an operation that forms a new trait by removing a method from an existing trait. (Combining this with the alias operation yields a shallow rename operation).

If a method is excluded from a trait, that method must be provided by the class that consumes the trait, or by a parent class of that class. This is because the methods provided by the trait might call the excluded method.

Trait composition is commutative (i.e. given traits A and B, A + B is equivalent to B + A) and associative (i.e. given traits A, B, and C, (A + B) + C is equivalent to A + (B + C)).

Limitations
While traits offer significant advantages over many alternatives, they do have their own limitations.

Required methods 
If a trait requires the consuming class to provide certain methods, the trait cannot know if those methods are semantically equivalent to the trait's needs. For some dynamic languages, such as Perl, the required method can only be identified by a method name, not a full method signature, making it harder to guarantee that the required method is appropriate.

Excluding methods 
If a method is excluded from a trait, that method becomes a 'required' method for the trait because the trait's other methods might call it.

Supported languages
Traits come originally from the programming language Self and are supported by the following programming languages:

 AmbientTalk: Combines the properties of Self traits (object-based multiple inheritance) and Smalltalk's Squeak traits (requiring explicit composition of traits by the programmer). It builds on the research on stateful and freezable traits to enable state within traits, which was not allowed in the first definitions.
C#: Since version 8.0, C# has support for default interface methods, which have some properties of traits.
 C++: Used in Standard Template Library and the C++ Standard Library to support generic container classes and in the Boost TypeTraits library.
 Curl: Abstract classes as mixins permit method implementations and thus constitute traits by another name.
 Fortress
 Groovy: Since version 2.3
 Haskell: In Haskell, Traits are known as Type classes.
 Haxe: Since version 2.4.0. Called Static Extension in the manual, it uses using keyword
 Java: Since version 8, Java has support for default methods, which have some properties of traits.
 JavaScript: Traits can be implemented via functions and delegations or through libraries that provide traits.
 Julia: Several packages implement traits, e.g.,
 Kotlin: Traits have been called interfaces since M12.
 Lasso
 Mojo: Since version 0.6.0
 OCaml: Traits can be implemented using a variety of language features: module and module type inclusion, functors and functor types, class and class type inheritance, et cetera.
 Perl: Called roles, they are implemented in Perl libraries such as Moose, Role::Tiny and Role::Basic. Roles are part of the sister language Raku.  With the acceptance of the Corinna OOP Proposal Perl will have roles native to the language as part of a modern OOP system.
 PHP: Since version 5.4, PHP allows users to specify templates that provide the ability to "inherit" from more than one (trait-)class, as a pseudo multiple inheritance.
 Python: Via a third-party library, or via higher-order mixin classes
 Racket: Supports traits as a library and uses macros, structures, and first-class classes to implement them.
 Ruby: Module mixins can be used to implement traits.
 Rust
 Scala trait is builtin supported with the key word trait.
 Smalltalk: Traits are implemented in two dialects of Smalltalk, Squeak and Pharo.
 Swift: Traits can be implemented with protocol extensions.

Examples

C# 
On C# 8.0, it is possible to define an implementation as a member of an interface.using System;

namespace CSharp8NewFeatures;

interface ILogger
{
    // Traditional interface methods
    void Log(string message);
    void LogError(Exception exception);

    // Default interface method
    void LogWarning(string message)
    {
        Console.WriteLine(message);
    }        
}

class Logger : ILogger
{
    public void Log(string message)
    {
        Console.WriteLine(message);
    }

    public void LogError(Exception exception)
    {
        Console.WriteLine(exception.ToString());
    }
}

class Program
{
    static void Main(string[] args)
    {
        ILogger logger = new Logger();

        logger.LogWarning("Some warning message");
    }
}

PHP 
This example uses a trait to enhance other classes:
// The template
trait TSingleton
{
    private static $_instance = null;

    private function __construct() {} // Must have private default constructor and be aware not to open it in the class

    public static function getInstance()
    {
        if (null === self::$_instance) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }
}

class FrontController
{
    use TSingleton;
}

// Can also be used in already extended classes
class WebSite extends SomeClass
{
    use TSingleton;
}

This allows simulating aspects of multiple inheritance:
trait TBounding
{
    public $x, $y, $width, $height;
}

trait TMoveable
{
    public function moveTo($x, $y)
    {
        // …
    }
}

trait TResizeable
{
    public function resize($newWidth, $newHeight)
    {
        // …
    }
}

class Rectangle
{
    use TBounding, TMoveable, TResizeable;

    public function fillColor($color)
    {
        // …
    }
}

Rust 
A trait in Rust declares a set of methods that a type must implement. Rust compilers require traits to be explicated, which ensures the safety of generics in Rust.

// type T must have the "Ord" trait
// so that ">" and "<" operations can be done
fn max<T: Ord>(a: &[T]) -> Option<&T> {
    let mut result = a.first()?;
    for n in a {
        if *n > *result {
            result = &n;
        }
    }
    Some(result)
}

To simplify tedious and repeated implementation of traits like Debug and Ord, the derive macro can be used to request compilers to generate certain implementations automatically. Derivable traits include: Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord and Hash.

See also
 Extension method
 Interface (object-oriented programming)
 Parametric polymorphism
 UFCS

References

External links
 

C++
Programming language topics
Type theory
Articles with example C Sharp code
Articles with example PHP code
Articles with example Rust code