
- Scala - Home
- Scala - Overview
- Scala - Features
- Scala - Environment Setup
- Scala - Build Tool (SBT)
- Scala - REPL
- Scala - Dot & Dotty
- Scala - Basic Syntax
- Scala - Hello World Program
- Scala - Identifiers
- Scala - Keywords
- Scala - Comments
- Scala - Code Blocks
- Scala - Semicolon
- Scala - Constructs
- Scala - Expressions
- Scala - Input and Output
- Scala - Optional Braces
- Scala - Underscore (_)
- Data Types and Variables
- Scala - Data Types
- Scala - Type Bounds
- Scala - Context Bound
- Scala - Variances
- Scala - Type Hierarchy
- Scala - Variables
- Scala - Variable Scopes
- Scala - Literals
- Scala - Numeric Types
- Scala - Boolean Types
- Scala - Char Type
- Scala - Unit Types
- Scala - Strings
- Scala - Arrays
- Scala - Null Type
- Scala - Nothing
- Scala - Any Type
- Scala - AnyRef Type
- Scala - Unified Types
- Scala - Dates and Times
- Scala - Ranges
- Scala - Multidimensional Arrays
- Scala - WrappedArray
- Scala - StringBuilder
- Scala - String Interpolation
- Scala - StringContext
- Scala - Type Casting
- Scala var vs val
- Scala Operators
- Scala - Operators
- Scala - Rules for Operators
- Scala - Arithmetic Operators
- Scala - Relational Operators
- Scala - Logical Operators
- Scala - Bitwise Operators
- Scala - Assignment Operators
- Scala - Operators Precedence
- Scala - Symbolic Operators
- Scala - Range Operator
- Scala - String Concatenation Operator
- Scala Conditional Statements
- Scala - IF ELSE
- Scala - IF-ELSE-IF-ELSE Statement
- Scala - Nested IF-ELSE Statement
- Scala Loop Statements
- Scala - Loop Statements
- Scala - while Loop
- Scala - do-while Loop
- Scala - Nested Loops
- Scala - for Loop
- Scala - break Statement
- Scala - yield Keyword
- Scala Classes & Objects
- Scala - Classes & Objects
- Scala - Constructors
- Scala - Auxiliary Constructor
- Scala - Primary Constructor
- Scala - This Keyword
- Scala - Nested Classes
- Scala - Getters and Setters
- Scala - Object Private Fields
- Scala - Singleton Object
- Scala - Companion Objects
- Scala - Creating Executable Programs
- Scala - Stateful Object
- Scala - Enumerations
- Scala - Polymorphism
- Scala - Access Modifiers
- Scala - Apply Method
- Scala - Update Methods
- Scala - UnapplySeq Method
- Scala - Inheritance
- Scala - Extending a Class
- Scala - Method Overloading
- Scala - Method Overriding
- Scala - Generic Classes
- Scala - Generic Functions
- Scala - Superclass Construction
- Scala Methods & Functions
- Scala - Functions
- Scala - Main Methods
- Scala - Functions Call-by-Name
- Scala - Functions with Named Arguments
- Scala - Function with Variable Arguments
- Scala - Recursion Functions
- Scala - Default Parameter Values
- Scala - Functions without Parameters
- Scala - Implicit Parameters
- Scala - Higher-Order Functions
- Scala - Nested Functions
- Scala - Extension Methods
- Scala - Anonymous Functions
- Partially Applied Functions
- Scala - Lazy Val
- Scala - Pure Function
- Scala - Currying Functions
- Scala - Control Abstractions
- Scala - Corecursion
- Scala - Unfold
- Scala - Tail Recursion
- Scala - Infinite Sequences
- Scala - Dynamic Invocation
- Scala - Lambda Expressions
- Scala Collections
- Scala - Collections
- Mutable and Immutable Collections
- Scala - Lists
- Scala - Sets
- Scala - Maps
- Scala - TreeMap
- Scala - SortedMap
- Scala - Tuples
- Scala - Iterators
- Scala - Options
- Scala - Infinite Streams
- Scala - Parallel Collections
- Scala - Algebraic Data Types
- Scala Pattern Matching
- Scala - Pattern Matching
- Scala - Type Patterns
- Scala - Exception Handling
- Scala - Extractors
- Scala - Regular Expressions
- Scala Files I/O
- Scala - Files I/O
- Scala Advanced Concepts
- Scala - Closures
- Scala - Futures
- Scala - Promises
- Scala - Traits
- Scala - Trait Mixins
- Scala - Layered Traits
- Scala - Trait Linearization
- Scala - Sealed Traits
- Scala - Transparent Traits
- Scala - Literal Type Arithmetic
- Scala - Inline keyword
- Scala - Def, Var & Val
- Scala - Dropped Features
- Scala - BDD Testing
Scala - Comments
Scala trait mixins allow you to extend any number of traits with a class or abstract class. Scala traits, or a combination of traits and classes, or traits and abstract classes, can be extended using trait mixins.
Trait Mixins - Extending Traits and Mixing Them In
Scala traits provide a powerful way to compose behavior from multiple sources. You can mix in multiple traits into a single class to combine their behavior. Let's extend the previous example to include additional traits and see how they interact.
Example
trait Printable extends Any { def print(): Unit = println(this) } trait Movable { def move(dx: Int, dy: Int): Unit } trait Equal { def isEqual(obj: Any): Boolean def isNotEqual(obj: Any): Boolean = !isEqual(obj) } class Point(xc: Int, yc: Int) extends Equal with Printable with Movable { var x: Int = xc var y: Int = yc def isEqual(obj: Any): Boolean = obj.isInstanceOf[Point] && obj.asInstanceOf[Point].x == x && obj.asInstanceOf[Point].y == y def move(dx: Int, dy: Int): Unit = { x += dx y += dy } override def print(): Unit = println(s"Point($x, $y)") } object Demo { def main(args: Array[String]): Unit = { val p1 = new Point(2, 3) val p2 = new Point(2, 4) val p3 = new Point(2, 3) println(p1.isNotEqual(p2)) println(p1.isNotEqual(p3)) println(p1.isNotEqual(2)) p1.print() p1.move(1, 1) p1.print() } }
Save the above program in Demo.scala. The following commands are used to compile and execute this program.
Command
\>scalac Demo.scala \>scala Demo
The output will be −
true false true Point(2, 3) Point(3, 4)
Here, the Point class now mixes in the Printable and Movable traits in addition to the Equal trait. You can have multiple traits combined for rich set of behaviors to a class. The Point class implements the move method from the Movable trait. It overrides the print method from the Printable trait to provide a custom string representation.
Advanced Trait Mixins
You can also define fields in traits for complex behaviors. Following is the example which shows you how advanced trait mixins −
Example
trait Equal { def isEqual(obj: Any): Boolean } trait Printable { def print(): Unit } trait Movable { def move(dx: Int, dy: Int): Unit } trait Timestamped { var timestamp: Long = System.currentTimeMillis() def updateTimestamp(): Unit = { timestamp = System.currentTimeMillis() } } class Point(xc: Int, yc: Int) extends Equal with Printable with Movable with Timestamped { var x: Int = xc var y: Int = yc def isEqual(obj: Any): Boolean = obj.isInstanceOf[Point] && obj.asInstanceOf[Point].x == x && obj.asInstanceOf[Point].y == y def move(dx: Int, dy: Int): Unit = { x += dx y += dy updateTimestamp() } override def print(): Unit = println(s"Point($x, $y) at $timestamp") } object Demo { def main(args: Array[String]): Unit = { val p1 = new Point(2, 3) p1.print() p1.move(1, 1) p1.print() } }
Save the above program in Demo.scala. The following commands are used to compile and execute this program.
Command
\>scalac Demo.scala \>scala Demo
The output will be −
Point(2, 3) at 1628609214000 Point(3, 4) at 1628609215000
Here, the Point class also mixes in the Timestamped trait. It has field and method to update the timestamp. So you can use traits to add fields and methods to a class to enrich its behavior and state.
Trait Mixins Summary
- Traits are used to compose behavior in Scala. You can mix multiple traits into a single class to combine their functionalities.
- You can use traits to define reusable behaviors that can be mixed into multiple and unrelated classes. So, it promotes code reuse and modularity.
- You can have partially implemented methods in traits. So you can provide default behavior that can be overridden by classes mixing in the trait.
- You can also define fields, which can be used for adding state to classes that mix in the trait.
- You can use universal traits for value classes to extend traits.