Rename and Override equals method in case class
Solution 1
The compiler will not generate equals
(and hashCode
, respectively) for case classes that already come with an equals
, i.e., that inherit one or declare one themselves. Read more about this in this blog entry. AFAIK the only thing you can do is to implement structural equality by using productIterator
provided by the Product trait that case classes extend, just as you did in equalsByAttributes
.
Solution 2
Do not change equals on case classes. If you need to do so, do not make your classes case classes. Changing case class methods will make the code behave unexpectedly (that is, unlike case classes), which will increase maintenance cost, break everything that assumes case classes work like case classes, make people's life miserable and get a lot of programmers to hate your guts.
In other words, it's not worth it. Don't do that.
Stefan Endrullis
Updated on July 02, 2022Comments
-
Stefan Endrullis almost 2 years
I want to define a trait named
Ext
that renames the existingequals
method toequalsByAttributes
and defines a newequals
method at the same time. The trait is used to extend case classes. My current solution looks somehow hacky:case class A(id: Int) extends Ext trait Ext { p: Product => // new implementation override def equals(obj: Any) = obj match { case that: AnyRef => this eq that case _ => false } // reimplementation of old equals implementation def equalsByAttributes(obj: Any) = obj match { case that: Product => if (this.getClass.isAssignableFrom(that.getClass) || that.getClass.isAssignableFrom(this.getClass)) p.productIterator.toList == that.productIterator.toList else false case _ => false } }
I wonder if there is a direct way to reference
A
'sequals
method inequalsByAttributes
so that one can avoid the reimplementation of this method?Edit 2012-07-12
Since there is a solution for referencing super implementations with
super.METHOD_NAME
I thought there must be a similar syntax such asoverridden.METHOD_NAME
for accessing specific implementations in the base class/trait that is going to be extended by the trait, so that myExt
trait would look like this:trait Ext { p: Product => override def equals(obj: Any) = ... def equalsByAttributes(obj: Any) = overridden.equals(obj) }