他のものを探している間、偶然の一致から、私は悪魔的なケースクラスの継承がいかにであるかについてのいくつかのコメントに出会いました。 ProductN
と呼ばれるもの、悪党と王、エルフとウィザードがあり、ケースクラスの継承により、ある種の非常に望ましいプロパティがどのように失われるかがありました。では、ケースクラスの継承で何が問題になっていますか?
一言:equality
case
クラスには、equals
およびhashCode
の実装が付属しています。 equals
と呼ばれる同値関係は次のように機能します(つまり、次のプロパティが必要です)。
x
; x equals x
はtrue
(再帰的)ですx
、y
、z
;もしx equals y
およびy equals z
、次にx equals z
(推移的)x
の場合、y
;もしx equals y
、次にy equals x
(対称)継承階層内で同等性を許可するとすぐに、2と3を解除できます。これは、次の例で簡単に示されます。
case class Point(x: Int, y: Int)
case class ColoredPoint(x: Int, y: Int, c: Color) extends Point(x, y)
それから私達は持っています:
Point(0, 0) equals ColoredPoint(0, 0, RED)
しかしではない
ColoredPoint(0, 0, RED) equals Point(0, 0)
すべてのクラス階層にこの問題がある可能性があると主張するかもしれませんが、これは事実です。しかし、(他の理由の中でも)開発者の観点から等価性を単純化するために特別にケースクラスが存在するため、それらを振る舞わせる非直感的は、独自の目標の定義です!
他の理由もありました。特に copy
が期待どおりに機能しなかった および パターンマッチャーとの相互作用 であるという事実。