
- 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 - Extension Methods
You can add new functionality to existing types without modifying their original code and using inheritance.
Extension Methods
Extension methods are methods that can be added to existing classes and objects. You can add extension methods even if you do not have access to their original source code. Extension methods are used when you want to add utility functions to classes that you do not own and cannot change. So, your code will be more expressive and readable. You can call more methods on instances of these types directly.
Definition
Extension method is a method added to an existing type using implicit conversions and using the extension keyword in Scala 3. So, you can add new methods to existing types without modifying their original code.
Syntax
The syntax of extension methods in Scala 3 is -
extension (x: Type) def methodName(params: Type*): ReturnType = { // method body }
Example of Extension Methods
The following example shows defining and using an extension method in Scala programming −
object Demo { extension (s: String) def greet: String = s"Hello, $s!" def main(args: Array[String]): Unit = { println("World".greet) } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Hello, World!
In the example, the greet method is added to String type using extension method. So you can call greet directly on any String instance.
Advantages of Extension Methods
There are various advantages of extension methods in Scala. You can add functionality to existing types without modifying their original code. So you can reuse code and reduce redundancy.
You can encapsulate utility functions and keep them close to the types they extend. So you can organize code properly. You can also enhance types with new methods when you do not have control over the source code of the types.
Extension Methods with Parameters
Extension methods can also take parameters. So it provides even more flexibility.
Syntax
The syntax of extension methods with parameters is -
extension (x: Type) def methodName(param1: ParamType1, param2: ParamType2): ReturnType = { // method body }
Example
Consider the example of an extension method with parameters in Scala programming -
object Demo { extension (s: String) def repeat(n: Int): String = s * n def main(args: Array[String]): Unit = { println("Hello".repeat(3)) } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
HelloHelloHello
In the example, the repeat method is added to the String type. So, you can repeat the string a specified number of times.
Chaining Extension Methods
You can chain multiple extension methods together. So, your code will be more expressive.
Syntax
The syntax for chaining extension methods is -
extension (x: Type) def firstExtension(params: Type*): ReturnType = { // first method body } extension (x: Type) def secondExtension(params: Type*): ReturnType = { // second method body }
Example
Consider the example of chaining extension methods in Scala programming −
object Demo { extension (s: String) def capitalizeWords: String = s.split(" ").map(_.capitalize).mkString(" ") def reverseWords: String = s.split(" ").reverse.mkString(" ") def main(args: Array[String]): Unit = { println("hello world".capitalizeWords.reverseWords) } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
World Hello
In the example, the capitalizeWords and reverseWords methods are added to the String type. You can chain these methods together to achieve more complex transformations.
Extension Methods for Collections
You can use extension methods with collections. You can add custom methods to collections to simplify operations.
Syntax
The syntax for extension methods with collections is -
extension [T](list: List[T]) def methodName(params: Type*): ReturnType = { // method body }
Example
Consider the example of adding an extension method to a List in Scala programming -
object Demo { extension [T](list: List[T]) def second: Option[T] = list.drop(1).headOption def main(args: Array[String]): Unit = { val nums = List(1, 2, 3, 4) println(nums.second) // Output: Some(2) val emptyList = List() println(emptyList.second) // Output: None } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Some(2) None
In the example, the second method is added to the List type. So you can get the second element of the list, if it exists.
Extension Methods with Type Classes
You can use extension methods in conjunction with type classes to provide more generic and reusable code.
Syntax
The syntax for extension methods with type classes is -
trait TypeClass[A] { def method(value: A): ReturnType } object TypeClassInstances { implicit val typeClassInstance: TypeClass[Type] = new TypeClass[Type] { def method(value: Type): ReturnType = { // method implementation } } } extension [A](value: A)(using typeClass: TypeClass[A]) def extensionMethod: ReturnType = typeClass.method(value)
Example
Consider the example of using extension methods with type classes in Scala programming -
trait Printable[A] { def format(value: A): String } object PrintableInstances { implicit val printableInt: Printable[Int] = new Printable[Int] { def format(value: Int): String = s"Int($value)" } implicit val printableString: Printable[String] = new Printable[String] { def format(value: String): String = s"String($value)" } } object Demo { import PrintableInstances._ extension [A](value: A)(using printable: Printable[A]) def print: String = printable.format(value) def main(args: Array[String]): Unit = { println(123.print) println("hello".print) } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Int(123) String(hello)
In the example, the print method is added to any type A that has implicit Printable[A] instance. So you can print different types in a consistent format.
Extension Methods Summary
- You can add new functionality to existing types without modifying their original code.
- It enhances code reuse, encapsulation, and flexibility.
- You can define extension methods using the extension keyword in Scala 3.
- Extension methods can take parameters and be chained together for more expressive code.
- You can use extension methods with collections to simplify operations.
- You can use extension methods combined with type classes. It provides more generic and reusable code.