Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rename and Override equals method in case class

I want to define a trait named Ext that renames the existing equals method to equalsByAttributes and defines a new equals 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's equals method in equalsByAttributes 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 as overridden.METHOD_NAME for accessing specific implementations in the base class/trait that is going to be extended by the trait, so that my Ext trait would look like this:

trait Ext { p: Product =>
    override def equals(obj: Any) = ...

    def equalsByAttributes(obj: Any) = overridden.equals(obj)
}
like image 778
Stefan Endrullis Avatar asked Jul 09 '12 12:07

Stefan Endrullis


People also ask

When to override equals in java?

Override equals() in Java In Java, Overriding is when the child class or the subclass has the same execution of method as declared in the parent class. The equals() method compares two strings. If the data of one string object is the same as the other, it returns True value otherwise False.

Why do we override equals method in Java?

All classes in Java inherit from the Object class, directly or indirectly (See point 1 of this). The Object class has some basic methods like clone(), toString(), equals(),.. etc. We can override the equals method in our class to check whether two objects have same data or not.

Can case class have methods?

Case Classes You can construct them without using new. case classes automatically have equality and nice toString methods based on the constructor arguments. case classes can have methods just like normal classes.

Why should we override equals method in C#?

For a value type, you should always override Equals, because tests for equality that rely on reflection offer poor performance. You can also override the default implementation of Equals for reference types to test for value equality instead of reference equality and to define the precise meaning of value equality.


2 Answers

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.

like image 111
Daniel C. Sobral Avatar answered Sep 23 '22 09:09

Daniel C. Sobral


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.

like image 39
Malte Schwerhoff Avatar answered Sep 20 '22 09:09

Malte Schwerhoff