programing tip

케이스 클래스 상속에 대해 * 그렇게 * 잘못된 것은 무엇입니까?

itbloger 2020. 11. 15. 10:59
반응형

케이스 클래스 상속에 대해 * 그렇게 * 잘못된 것은 무엇입니까?


다른 것을 찾는 동안 우연의 일치로 나는 사악한 케이스 클래스 상속이 얼마나되는지에 대한 의견을 거의 발견하지 못했습니다. ProductN, 비참한 사람과 왕, 엘프와 마법사 라는 것이 있었고 케이스 클래스 상속으로 인해 어떤 종류의 매우 바람직한 속성이 어떻게 손실되는지가있었습니다. 그렇다면 케이스 클래스 상속이 그렇게 잘못된 것은 무엇입니까?


한 단어 : 평등

case클래스는 제공되는 equalshashCode. 다음과 같이 equals작동 하는 등가 관계 (즉, 다음 속성이 있어야 함) :

  1. 모두를 위해 x; x equals x이다 true(반사적)
  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) 

그러면 다음이 있습니다.

Point(0, 0) equals ColoredPoint(0, 0, RED)

그러나 하지

ColoredPoint(0, 0, RED) equals Point(0, 0)

모든 클래스 계층에이 문제가있을 수 있다고 주장 할 수 있으며 이는 사실입니다. 그러나 케이스 클래스는 특히 개발자의 관점에서 평등을 단순화하기 위해 존재하므로 (다른 이유로) 비 직관적으로 작동하도록 하는 것은 자체 목표의 정의가 될 것입니다!


다른 이유도있었습니다. 특히 사실은 그 copy예상대로 작동하지 않았다패턴 매처과의 상호 작용 .


그것은 전반적으로 사실이 아닙니다. 그리고 이것은 거짓말보다 더 나쁩니다.

에서 언급 한 바와 같이 aepurniet 패턴 매칭이 어떤지 정확히 작동해야하기 때문에 평등을 다시 정의해야 정의 영역을 수축 어떤 경우 클래스 후계자에 (시도가 일치하는 경우 PointColoredPoint그 이후는 일치하지 않습니다 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 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) = ???

참고 URL : https://stackoverflow.com/questions/11158929/what-is-so-wrong-with-case-class-inheritance

반응형