According to scala-wartremover static analysis tool I have to put "final" in front of every case classes I create: error message says "case classes must be final".
According to scapegoat (another static analysis tool for Scala) instead I shouldn't (error message: "Redundant final modifier on case class")
Who is right, and why?
It is not redundant in the sense that using it does change things. As one would expect, you cannot extend a final case class, but you can extend a non-final one. Why does wartremover suggest that case classes should be final? Well, because extending them isn't really a very good idea. Consider this:
Really?
Bar(1,1)
equalsBar(1,2)
? This is unexpected. But wait, there is more:A copy of
Bar
has typeFoo
? Can this be right?Surely, we can fix this by overriding the
.equals
(and.hashCode
, and.toString
, and.unapply
, and.copy
, and also, possibly,.productIterator
,.productArity
,.productElement
etc.) method onBar
andBaz
. But "out of the box", any class that extends a case class would be broken.This is the reason, you can no longer extend a case class by another case class, it has been forbidden since, I think scala 2.11. Extending a case class by a non-case class is still allowed, but, at least, in wartremover's opinion isn't really a good idea.