在使用它时,它并不是多余的,因为使用它确实会改变事物。正如人们所预期的,您不能扩展一个终态(final)的case class,但可以扩展一个非终态的case class。
那么,为什么wartremover建议将case class设置为final呢?这是因为将它们扩展并不是一个好主意。考虑以下内容:
scala> case class Foo(v:Int)
defined class Foo
scala> class Bar(v: Int, val x: Int) extends Foo(v)
defined class Bar
scala> new Bar(1, 1) == new Bar(1, 1)
res25: Boolean = true
scala> new Bar(1, 1) == new Bar(1, 2)
res26: Boolean = true
真的吗?Bar(1,1)
等于Bar(1,2)
?这不是预料中的。但是,稍等,还有更多:
scala> new Bar(1,1) == Foo(1)
res27: Boolean = true
scala> class Baz(v: Int) extends Foo(v)
defined class Baz
scala> new Baz(1) == new Bar(1,1)
res29: Boolean = true
scala> println (new Bar(1,1))
Foo(1)
scala> new Bar(1,2).copy()
res49: Foo = Foo(1)
Bar
的复制品具有类型Foo
?这可能是正确的吗?
当然,我们可以通过覆盖Bar
和Baz
上的.equals
(以及.hashCode
、.toString
、.unapply
、.copy
、可能还有.productIterator
、.productArity
、.productElement
等)方法来修复这个问题。但是,“开箱即用”,任何扩展案例类的类都将出现问题。
这就是为什么自Scala 2.11以来,不能再通过另一个案例类来扩展案例类的原因。仍然允许通过非案例类来扩展案例类,但至少在wartremover的观点中,这并不是一个好主意。