In Scala, operator overloading is simply a matter of defining methods with the names of the desired operators. Unlike some other programming languages, in Scala, you can use symbols, such as ‘+‘, ‘-‘, ‘*‘, and others as method names. These methods can then be called using infix notation, which looks like the operator is being used between two operands. Keep in mind that Scala actually does not have special syntax for operators but treats them like regular methods.
Here’s an example. Let’s create a simple ‘Complex‘ class representing complex numbers, and overload the ‘+‘ and ‘*‘ operators for adding and multiplying complex numbers.
class Complex(val real: Double, val imag: Double) {
def +(other: Complex): Complex = {
new Complex(real + other.real, imag + other.imag)
}
def *(other: Complex): Complex = {
new Complex(
real * other.real - imag * other.imag,
real * other.imag + imag * other.real)
}
override def toString: String = s"($real + ${imag}i)"
}
Here we define a ‘Complex‘ class with two methods ‘+‘ and ‘*‘. Each method expects another ‘Complex‘ object as an argument and returns a new ‘Complex‘ object resulting from the addition or multiplication.
Now, we can create complex numbers and use the overloaded operators:
val c1 = new Complex(3, 4)
val c2 = new Complex(1, -1)
val c3 = c1 + c2
val c4 = c1 * c2
println(c3) // (4.0 + 3.0i)
println(c4) // (7.0 + 1.0i)
Here, we create two complex numbers ‘c1‘ and ‘c2‘, and then add and multiply them using the methods ‘+‘ and ‘*‘ using infix notation. The code ‘c1 + c2‘ is actually calling the ‘+‘ method on ‘c1‘ with ‘c2‘ as an argument. This also applies to ‘c1 * c2‘, which calls the ‘*‘ method on ‘c1‘ with ‘c2‘ as an argument. The results are printed as expected.
Note that when defining methods with symbolic names, you should be careful to balance the needs of readability and expressivity in your code. Using too many custom operators might make your code difficult to understand for other developers.