-1

My knowledge is a little bit vague on Scala's case classes.

I know that case classes automatically get functions such as appply and unapply and also an equality check (I'm assuming it's the equals method)

The automatic equality check that comes with a case class is not always the correct one for an application.

My question is this: If I have a case class which extends an abstract class, and the abstract class has its equals(that:Any) overridden, will the case class inherit the equality check or is it still going to be the automatic equality check?

Anton
  • 2,282
  • 26
  • 43
  • 7
    You know that you can try this out by yourself by just writing some lines of code? It wouldn't even take you as long as writing such a question. – kiritsuku Jan 15 '15 at 17:24
  • That is a fair point. But I was hoping that people could point out potential pitfalls. For example: what does `Option.contains` use for equality checks? I don't know, and there are many other functions that do eqaulity checks internally. – Anton Jan 15 '15 at 17:45
  • 2
    @Andrey some research is expected when asking a question on SO. Do some experiments on your own and if you don't know something, try to look it up (google, documentation, SO itself). When you're done with this, you've probably done enough research to post a question. For instance the answer to the `Option.contains` question is easily answered in the official scala doc. – Gabriele Petronella Jan 15 '15 at 18:16

1 Answers1

1

You could read this brief section and it wouldn't even take you as long as writing some lines of code to try it out.

It says the case class gets copy, and also equals, hashCode and toString unless one is inherited or defined. The latter must be concrete and defined elsewhere than in AnyRef.

That means mixing in a trait that declares an equals doesn't disable equals.

Now I have to go write a line of code to confirm it...

scala> trait Ickwals { def equals(other: Any): Boolean }
defined trait Ickwals

scala> case class C(i: Int) extends Ickwals
defined class C

scala> :javap C#equals
  public boolean equals(java.lang.Object);
    descriptor: (Ljava/lang/Object;)Z
[generated]

scala> trait Ickwals { override def equals(other: Any): Boolean = false }
defined trait Ickwals

scala> case class C(i: Int) extends Ickwals
defined class C

scala> :javap C#equals
  public boolean equals(java.lang.Object);
    descriptor: (Ljava/lang/Object;)Z
[as implemented]

scala> trait Ickwals { def equals(other: Any): Boolean ; def copy(i: Int): Nothing }
defined trait Ickwals

scala> case class C(i: Int) extends Ickwals
<console>:8: error: class C needs to be abstract, since method copy in trait Ickwals of type (i: Int)Nothing is not defined
       case class C(i: Int) extends Ickwals
                  ^
som-snytt
  • 39,429
  • 2
  • 47
  • 129