Home > Back-end >  Is it possible in Scala 3 overriding a method in superclass with extension methods?
Is it possible in Scala 3 overriding a method in superclass with extension methods?

Time:09-21

I tried to override the equals method of java.lang.Object by doing this:

  extension(cellTower: CellTower)
    // CellTower class unfortunately has no equals() implementation, 
    // but a toString(), so we use this for equality
    def equals(other: Object): Boolean = cellTower.toString == other.toString

It didn't get used for equality (==).

Is this impossible with Scala 3 extension methods or am I doing something wrong?

CodePudding user response:

This is not possible: Object already has the method equals, all reference types extend Object, so the compiler will always take the overridden java.lang.Object.equals, and never look for any extension methods.

A more complete version of your example would look a little bit like this:

case class Foo(a: Int, b: String):
  override def toString = b

extension (foo: Foo)
  def equals(other: AnyRef): Boolean = foo.toString == other.toString

val u = Foo(42, "x")
val v = Foo(58, "x")

println(u.toString == v.toString) // true
println(u == v) // false

What you could do however, is to use your own implementation of Eq with ===:

import cats.kernel.Eq
import cats.syntax.eq._

case class Foo(a: Int, b: String):
  override def toString = b

object Foo:
  given Eq[Foo] with
    def eqv(x: Foo, y: Foo): Boolean = x.b == y.b

val u = Foo(42, "x")
val v = Foo(58, "x")

println(u.toString == v.toString) // true
println(u == v)                   // false
println(u === v)                  // true

Same applies to toString -> Show and hashCode -> Hash (link to scaladoc for cats.kernel.Hash). Whenever you need more control over equality / hashing / string-representation, consider using the corresponding type classes instead.

  • Related