In
computer programming
Computer programming or coding is the composition of sequences of instructions, called computer program, programs, that computers can follow to perform tasks. It involves designing and implementing algorithms, step-by-step specifications of proc ...
, a trait is a
language
Language is a structured system of communication that consists of grammar and vocabulary. It is the primary means by which humans convey meaning, both in spoken and signed language, signed forms, and may also be conveyed through writing syste ...
concept that represents a set of
methods that can be used to extend the functionality of a
class
Class, Classes, or The Class may refer to:
Common uses not otherwise categorized
* Class (biology), a taxonomic rank
* Class (knowledge representation), a collection of individuals or objects
* Class (philosophy), an analytical concept used d ...
.
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
JSON (JavaScript Object Notation, pronounced or ) is an open standard file format and electronic data interchange, data interchange format that uses Human-readable medium and data, human-readable text to store and transmit data objects consi ...
. Historically, there have been several approaches to solve this without duplicating the code in every class needing the behavior. Other approaches include
multiple inheritance
Multiple inheritance is a feature of some object-oriented computer programming languages in which an object or class can inherit features from more than one parent object or parent class. It is distinct from single inheritance, where an object ...
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
Multiple inheritance is a feature of some object-oriented computer programming languages in which an object or class can inherit features from more than one parent object or parent class. It is distinct from single inheritance, where an object ...
. 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
In mathematics, a binary operation is commutative if changing the order of the operands does not change the result. It is a fundamental property of many binary operations, and many mathematical proofs depend on it. Perhaps most familiar as a pr ...
(i.e. given traits ''A'' and ''B'', ''A'' + ''B'' is equivalent to ''B'' + ''A'') and
associative
In mathematics, the associative property is a property of some binary operations that rearranging the parentheses in an expression will not change the result. In propositional logic, associativity is a valid rule of replacement for express ...
(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
In computer science, a type signature or type annotation defines the inputs and outputs of a function, subroutine or method. A type signature includes the number, types, and order of the function's arguments. One important use of a type signat ...
, 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
In philosophy, the self is an individual's own being, knowledge, and values, and the relationship between these attributes.
The first-person perspective distinguishes selfhood from personal identity. Whereas "identity" is (literally) same ...
and are supported by the following programming languages:
* AmbientTalk: Combines the properties of Self traits (object-based multiple inheritance) and Smalltalk
Smalltalk is a purely object oriented programming language (OOP) that was originally created in the 1970s for educational use, specifically for constructionist learning, but later found use in business. It was created at Xerox PARC by Learni ...
's Squeak
Squeak is an object-oriented, class-based, and reflective programming language. It was derived from Smalltalk-80 by a group that included some of Smalltalk-80's original developers, initially at Apple Computer, then at Walt Disney Imaginee ...
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
The Standard Template Library (STL) is a software library originally designed by Alexander Stepanov for the C++ programming language that influenced many parts of the C++ Standard Library. It provides four components called ''algorithms'', '' ...
and the C++ Standard Library
The C standard library, sometimes referred to as libc, is the standard library for the C programming language, as specified in the ISO C standard.ISO/ IEC (2018). '' ISO/IEC 9899:2018(E): Programming Languages - C §7'' Starting from the origina ...
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
A fortification (also called a fort, fortress, fastness, or stronghold) is a military construction designed for the defense of territories in warfare, and is used to establish rule in a region during peacetime. The term is derived from L ...
* Groovy
''Groovy'' (or, less commonly, ''groovie'' or ''groovey'') is a slang colloquialism popular during the 1960s and 1970s. It is roughly synonymous with words such as "excellent", "fashionable", or "amazing", depending on context.
History
The word ...
: Since version 2.3
* Haskell
Haskell () is a general-purpose, statically typed, purely functional programming language with type inference and lazy evaluation. Designed for teaching, research, and industrial applications, Haskell pioneered several programming language ...
: In Haskell, Traits are known as Type class
In computer science, a type class is a type system construct that supports ad hoc polymorphism. This is achieved by adding constraints to type variables in parametrically polymorphic types. Such a constraint typically involves a type class T a ...
es.
* Haxe
Haxe is a high-level cross-platform programming language and compiler that can produce applications and source code for many different computing platforms from one code-base. It is free and open-source software, released under an MIT License. ...
: Since version 2.4.0. Called ''Static Extension'' in the manual, it uses using
keyword
* Java
Java is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea (a part of Pacific Ocean) to the north. With a population of 156.9 million people (including Madura) in mid 2024, proje ...
: Since version 8, Java has support for ''default methods'', which have some properties of traits.
* JavaScript
JavaScript (), often abbreviated as JS, is a programming language and core technology of the World Wide Web, alongside HTML and CSS. Ninety-nine percent of websites use JavaScript on the client side for webpage behavior.
Web browsers have ...
: 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
A lasso or lazo ( or ), also called reata or la reata in Mexico, and in the United States riata or lariat (from Mexican Spanish lasso for roping cattle), is a loop of rope designed as a restraint to be thrown around a target and tightened when ...
* Mojo: Since version 0.6.0
* OCaml
OCaml ( , formerly Objective Caml) is a General-purpose programming language, general-purpose, High-level programming language, high-level, Comparison of multi-paradigm programming languages, multi-paradigm programming language which extends the ...
: 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
Perl is a high-level, general-purpose, interpreted, dynamic programming language. Though Perl is not officially an acronym, there are various backronyms in use, including "Practical Extraction and Reporting Language".
Perl was developed ...
: Called ''roles'', they are implemented in Perl libraries such as Moose
The moose (: 'moose'; used in North America) or elk (: 'elk' or 'elks'; used in Eurasia) (''Alces alces'') is the world's tallest, largest and heaviest extant species of deer and the only species in the genus ''Alces''. It is also the tal ...
, 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
Multiple inheritance is a feature of some object-oriented computer programming languages in which an object or class can inherit features from more than one parent object or parent class. It is distinct from single inheritance, where an object ...
.
* 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
Ruby is a pinkish-red-to-blood-red-colored gemstone, a variety of the mineral corundum ( aluminium oxide). Ruby is one of the most popular traditional jewelry gems and is very durable. Other varieties of gem-quality corundum are called sapph ...
: ''Module mixins'' can be used to implement traits.
* Rust
Rust is an iron oxide, a usually reddish-brown oxide formed by the reaction of iron and oxygen in the catalytic presence of water or air moisture. Rust consists of hydrous iron(III) oxides (Fe2O3·nH2O) and iron(III) oxide-hydroxide (FeO(OH) ...
* Scala trait is builtin supported with the key word trait
.
* Smalltalk
Smalltalk is a purely object oriented programming language (OOP) that was originally created in the 1970s for educational use, specifically for constructionist learning, but later found use in business. It was created at Xerox PARC by Learni ...
: Traits are implemented in two dialects of Smalltalk, Squeak
Squeak is an object-oriented, class-based, and reflective programming language. It was derived from Smalltalk-80 by a group that included some of Smalltalk-80's original developers, initially at Apple Computer, then at Walt Disney Imaginee ...
[ and ]Pharo
Pharo is a Cross-platform software, cross-platform implementation of the classic Smalltalk-80 programming language and runtime system. It is based on the OpenSmalltalk virtual machine (VM) named Cog, which evaluates a dynamic, Reflective progr ...
.
* Swift
Swift or SWIFT most commonly refers to:
* SWIFT, an international organization facilitating transactions between banks
** SWIFT code
* Swift (programming language)
* Swift (bird), a family of birds
It may also refer to:
Organizations
* SWIF ...
: 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
class Logger : ILogger
class Program
PHP
This example uses a trait to enhance other classes:
// The template
trait TSingleton
class FrontController
// Can also be used in already extended classes
class WebSite extends SomeClass
This allows simulating aspects of multiple inheritance:
trait TBounding
trait TMoveable
trait TResizeable
class Rectangle
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(a: & -> Option<&T>
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
In object-oriented computer programming, an extension method is a method added to an object after the original object was compiled. The modified object is often a class, a prototype, or a type. Extension methods are features of some object-o ...
* Interface (object-oriented programming)
In object-oriented programming, an interface or protocol type is a data type that acts as an abstraction of a Class (computer science), class. It describes a set of method signatures, the implementations of which may be provided by multiple class ( ...
* Parametric polymorphism
In programming languages and type theory, parametric polymorphism allows a single piece of code to be given a "generic" type, using variables in place of actual types, and then instantiated with particular types as needed. Parametrically polymorph ...
* UFCS
References
External links
* {{cite web , url=http://scg.unibe.ch/research/traits , title=Traits: Composable Units of Behavior , website=Software Composition Group , publisher=University of Bern
C++
Programming language topics
Type theory
Articles with example C Sharp code
Articles with example PHP code
Articles with example Rust code