私は何か他のものを探していたのですが、単なる偶然の偶然のことではなく、私は邪悪なケースクラスの継承がどういうものかについてのコメントはほとんどありませんでした。 ProductN
と呼ばれるこの事がありました。惨めな人と王様、エルフとウィザード、そしてケースクラスの継承によって非常に望ましい財産が失われています。なぜケースクラスの継承で間違っているのですか?大文字と小文字のクラスの継承にはどうして*間違っていますか?
56
A
答えて
97
一言:平等
case
クラスはequals
とhashCode
の供給実装が付属しています。 equals
として知られている同値関係は、(すなわち、以下の特性を有していなければならない)、このように動作:全てx
について
- 。
x equals x
はtrue
(反射性) x
,y
,z
である。もしx equals y
およびy equals z
ならばx 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
did not work as expectedとinteraction with the pattern matcherという事実です。
-2
これは全体的に真実ではありません。そして、これは嘘よりも悪いです。パターンマッチングが正確(ColoredPoint
としてPoint
と一致しようとcolor
が存在しないので、それが一致しません)等式として動作しなければならないので、定義領域が平等を再定義しなければならない収縮いずれの場合クラス後継でaepurnietにより述べたよう
。
これは、ケースクラス階層の平等性をどのように実装できるかを理解するものです。
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) = ???
関連する問題
- 1. 小文字のwindows.hと大文字のWindows.hの違いはありますか?
- 2. Swift:文字列の文字が間違っています
- 3. ドイツ語の大文字小文字の大文字小文字
- 4. self .__ class__でクラスの継承が間違っていますか?
- 5. は小文字と大文字の両方と比較しています。
- 6. 大文字と小文字の区別から大文字小文字を区別しないものへ
- 7. 文字のチェンジャーを小文字から大文字に変換する(その逆):自分のコードで何が間違っていますか?
- 8. RouteValueDictionaryクラスのキーは大文字と小文字を区別しませんか?
- 9. Goは大文字小文字を区別しない文字列contains()関数を持っていますか?
- 10. IBM Case Manager:間違って「シーケンス番号の不一致を更新して」大文字小文字を保存しようとしています
- 11. mshtml.tlbの名前空間は、小文字から大文字に変わっていません
- 12. なぜscala値のクラス#toStringに大文字小文字のクラス情報が含まれていますか?
- 13. HTMLは大文字と小文字を区別しますか?
- 14. AutoMapperは大文字と小文字を区別しますか?
- 15. HTML.Partialは大文字と小文字を区別しますか?
- 16. メタキーワードは大文字と小文字を区別しますか?
- 17. は:大文字と小文字を区別しますか?
- 18. mysqlは大文字と小文字を区別しますか?
- 19. 文字列に大文字小文字を区別しない別の文字列が含まれているかどうかを確認できますか?
- 20. 大文字小文字の大文字の表示なし
- 21. 大文字と小文字の区別
- 22. 小文字と大文字のファイル名
- 23. 大文字と小文字の検索
- 24. Solrキーワードの小文字と大文字
- 25. URLの大文字と小文字の違いによる無限のリダイレクト - OpenIdConnect
- 26. Powershellを使用して、大文字と小文字の大文字と小文字を区別してユーザーIDを識別します。
- 27. 大文字または小文字の場合に行単位で文字を確認する方法と大文字と小文字を数えますか?
- 28. Cの大文字小文字から小文字へ
- 29. JavaScript内の文字列内の小文字と大文字の間のスペース
- 30. WPFは純粋に大文字と小文字を区別しますか?幅フィールドの「自動」値は大文字小文字を区別しますか?
少し丁寧なことはありますか?:) –
このような非対称の等価性は、オブジェクト指向のパラダイムにおいて有用なことであると思われます。同じように、型のレベルでは「ColoredPoint」は「Point」ですが、逆も同様です。しかし、おそらく 'subEquals'でも' equals'以外の何かを呼び出さなければならないでしょうか? –
@Luigi逆関係に 'canReplace'、' supersedes'、 'specify'、' override'がありますか? '> =' -nessを示すもの(または ''あなたが好きなら ':' 'あれば)です。 '<='ではなく '> ='で表現する方がはるかに簡単です。 –