Ответ 1
Это не избыточно в том смысле, что использование его действительно меняет вещи. Как и следовало ожидать, вы не можете продлить окончательный класс case, но вы можете расширить неконкретный. Почему wartremover предполагает, что классы классов должны быть окончательными? Ну, потому что расширение их на самом деле не очень хорошая идея. Рассмотрим это:
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
? Это может быть правильно?
Конечно, мы можем исправить это, переопределив .equals
(и .hashCode
и .toString
, и .unapply
, и .copy
, а также, возможно, .productIterator
, .productArity
, .productElement
и т.д.) на Bar
и Baz
. Но "из коробки" любой класс, который расширяет класс case, будет разбит.
По этой причине вы больше не можете расширять класс case другим классом case, это было запрещено, так как, я думаю, scala 2.11. Расширение класса case нестандартным классом все еще разрешено, но, по крайней мере, в решении wartremover на самом деле не очень хорошая идея.