케이스 클래스 상속에 대해 * 그렇게 * 잘못된 것은 무엇입니까?
다른 것을 찾는 동안 우연의 일치로 나는 사악한 케이스 클래스 상속이 얼마나되는지에 대한 의견을 거의 발견하지 못했습니다. ProductN
, 비참한 사람과 왕, 엘프와 마법사 라는 것이 있었고 케이스 클래스 상속으로 인해 어떤 종류의 매우 바람직한 속성이 어떻게 손실되는지가있었습니다. 그렇다면 케이스 클래스 상속이 그렇게 잘못된 것은 무엇입니까?
한 단어 : 평등
case
클래스는 제공되는 equals
및 hashCode
. 다음과 같이 equals
작동 하는 등가 관계 (즉, 다음 속성이 있어야 함) :
- 모두를 위해
x
;x equals x
이다true
(반사적) - 를 들어
x
,y
,z
, ifx equals y
및y equals z
thenx 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
예상대로 작동하지 않았다 및 패턴 매처과의 상호 작용 .
그것은 전반적으로 사실이 아닙니다. 그리고 이것은 거짓말보다 더 나쁩니다.
에서 언급 한 바와 같이 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 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
'programing tip' 카테고리의 다른 글
C ++ 0x : 람다를 참조로 매개 변수로받는 적절한 방법 (0) | 2020.11.15 |
---|---|
캔버스를 png 이미지로 저장하는 방법? (0) | 2020.11.15 |
강제 "가로"방향 모드 (0) | 2020.11.15 |
고 루틴 내부의 fmt.Println이 행을 인쇄하지 않는 이유는 무엇입니까? (0) | 2020.11.15 |
CSS를 사용하여 색상을 반전하려면 어떻게해야합니까? (0) | 2020.11.15 |