案例类继承的*so*错误是什么?

Ash*_*ary 66 inheritance scala case-class

在寻找别的东西时,我只是偶然发现了一些关于恶魔案例类继承的评论.这个东西被称为ProductN,可怜虫和国王,精灵和巫师,以及如何通过案例类继承丢失某种非常理想的属性.那么case类继承有什么问题呢?

oxb*_*kes 109

一句话:平等

case类提供了equals和提供的实现hashCode.等价关系,称为这样的equals工作(即必须具有以下属性):

  1. 为了所有人x; x equals xtrue(反身)
  2. 对于x,y,z,if x equals yy equals zthen 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) 
Run Code Online (Sandbox Code Playgroud)

然后我们有:

Point(0, 0) equals ColoredPoint(0, 0, RED)
Run Code Online (Sandbox Code Playgroud)

不是

ColoredPoint(0, 0, RED) equals Point(0, 0)
Run Code Online (Sandbox Code Playgroud)

您可能会争辩说所有类层次结构都可能存在这个问题,这是事实.但是案例类专门用于从开发人员的角度(以及其他原因)简化相等性,因此让它们行为非直观地定义为自己的目标!


还有其他原因; 值得注意的是,事实copy并未按预期工作与模式匹配器进行交互.

  • 看起来这种不对称等价在OO范例中会是一个有用的东西,就像在类型级别一样,"ColoredPoint"是一个"Point"但反之亦然.可能不得不称它为"等于"以外的东西......也许是`subEquals`? (2认同)
  • 通用的equals很容易实现,可以满足相等性,使类成为比较的一部分.复制事物看起来只是一个bug,与模式匹配器的交互应该起作用,就像非案例类层次结构一样. (2认同)