web-dev-qa-db-ja.com

ケースクラスの継承で何が悪いのですか?

他のものを探している間、偶然の一致から、私は悪魔的なケースクラスの継承がいかにであるかについてのいくつかのコメントに出会いました。 ProductNと呼ばれるもの、悪党と王、エルフとウィザードがあり、ケースクラスの継承により、ある種の非常に望ましいプロパティがどのように失われるかがありました。では、ケースクラスの継承で何が問題になっていますか?

66

一言:equality

caseクラスには、equalsおよびhashCodeの実装が付属しています。 equalsと呼ばれる同値関係は次のように機能します(つまり、次のプロパティが必要です)。

  1. すべてのx; x equals xtrue(再帰的)です
  2. xyz;もしx equals yおよびy equals z、次にx equals z(推移的)
  3. 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が期待どおりに機能しなかった および パターンマッチャーとの相互作用 であるという事実。

109
oxbow_lakes