什么是* *这样不妥情况下,类继承?什么是* *这样不妥情况下,类继承?(What is *so*

2019-06-02 18:19发布

虽然寻找别的东西,相当出纯粹的巧合,我偶然发现有关类继承如何毒辣的情况是几点意见。 有这个东西叫做ProductN ,坏蛋和国王,精灵和巫师,以及如何某种非常理想的财产损失与case类继承。 那么,什么是错用的情况下类继承?

Answer 1:

一个字: 平等

case类别配备了提供实现equalshashCode 。 等价关系,称为equals像这样的作品(即必须具有以下特性):

  1. 对于所有的x ; x equals xtrue (反身)
  2. 对于xyz ; 如果x equals yy equals z然后x equals z (传递)
  3. 对于xy ; 如果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)

你可能会认为,所有的类层次结构可能有这个问题,这是真的。 但是case类具体存在简化从开发人员的角度平等(除其他原因外),所以有他们的行为非直观的将是自己的目标定义!


还有其他一些原因,以及; 值得注意的是事实, copy没有按预期工作 ,并与模式匹配的交互 。



Answer 2:

这不是真正的整体。 这是比谎言更坏。

如前所述通过aepurniet在任何情况下类的继任者,其收缩的定义区域必须重新定义平等,因为模式匹配必须完全工作的平等(如果尝试匹配Point作为ColoredPoint话,就不会匹配,因为color是不存在的)。

这给予理解如何案件类层次的平等无法实施。

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)  // false
Point(0, 0) equals ColoredPoint(0, 0, null) // true

ColoredPoint(0, 0, RED) equals Point(0, 0)  // false
ColoredPoint(0, 0, null) equals Point(0, 0) // true

最后,它是能够满足甚至case类的继任者平等关系的要求(无平等的覆盖)。

case class ColoredPoint(x: Int, y: Int, c: String)
class RedPoint(x: Int, y: Int) extends ColoredPoint(x, y, "red")
class GreenPoint(x: Int, y: Int) extends ColoredPoint(x, y, "green")

val colored = ColoredPoint(0, 0, "red")
val red1 = new RedPoint(0, 0)
val red2 = new RedPoint(0, 0)
val green = new GreenPoint(0, 0)

red1 equals colored // true
red2 equals colored // true
red1 equals red2 // true

colored equals green // false
red1 equals green // false
red2 equals green // false

def foo(p: GreenPoint) = ???


文章来源: What is *so* wrong with case class inheritance?