Szukając czegoś innego, zupełnie przypadkowo natknąłem się na kilka komentarzy na temat tego, jak diabelskie dziedzictwo klas przypadków jest. Było to coś o nazwie ProductN
, nędzników i królów, elfów i czarodziejów oraz jak traci się jakąś bardzo pożądaną własność z dziedziczeniem klas spraw. Więc co jest nie tak z dziedziczeniem klasy przypadku?Co to jest * tak * nie tak z dziedziczeniem klasy spraw?
Odpowiedz
Jednym słowem: równość
case
klasy pochodzą z dostarczonym realizacji equals
i hashCode
. Stosunek równoważności, znany jako equals
działa w następujący sposób (to znaczy musi posiadać następujące właściwości)
- Dla wszystkich
x
;x equals x
jesttrue
(refleksyjny) - dla
x
,y
,z
; jeślix equals y
iy equals z
następnie (przechodnie) - Dla
x
,y
; jeślix equals y
następniey equals x
(symetrycznym)
Tak szybko, jak pozwalają na równość w hierarchii dziedziczenia można złamać 2 i 3. to jest trywialnie świadczy następujący przykład:
case class Point(x: Int, y: Int)
case class ColoredPoint(x: Int, y: Int, c: Color) extends Point(x, y)
Następnie mamy :
Point(0, 0) equals ColoredPoint(0, 0, RED)
Ale nie
ColoredPoint(0, 0, RED) equals Point(0, 0)
Można argumentować, że wszystkie hierarchie klas mogą mieć ten problem, i to prawda. Ale klasy przypadków istnieją specjalnie po to, aby uprościć równość z perspektywy programisty (między innymi), więc nieintuicyjnie zachowując je, zachowamy się tak, jakby to było .
Były też inne powody; w szczególności fakt, że copy
did not work as expected i interaction with the pattern matcher.
To nie jest całkowita prawda. A to jest gorsze niż kłamstwo.
Jak wspomniano przez aepurniet w każdym przypadku klasy następcy, który zwęża obszar definicja musi przedefiniować równości, ponieważ dopasowanie wzorca musi działać dokładnie jak równość (jeśli starają się dopasować Point
jak ColoredPoint
to nie będzie dopasowana od color
nie istnieje).
Dają one zrozumienie, w jaki sposób można wdrożyć równość hierarchii klas przypadków.
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
Ostatecznie jest to możliwe, aby zaspokoić wymagania względem równości nawet dla klasy sprawa następcy (bez przesłanianie równości).
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. Co jest nie tak z dziedziczeniem Square i Rectangle?
- 2. Co jest nie tak z ?? operator używany tak:
- 3. Co jest nie tak z mapowaniem dwukierunkowym?
- 4. Co jest nie tak z nowym Wyjątkiem?
- 5. Co jest nie tak z pisaniem "@ARGV || = '.';"?
- 6. Co jest nie tak z readline?
- 7. Co jest nie tak z parametrami wyjściowymi?
- 8. Co jest nie tak z moim algorytmem?
- 9. Co jest nie tak z ifstream seekg
- 10. Co jest nie tak z obiektem DateTime
- 11. Co jest nie tak z tym SQL?
- 12. Co jest nie tak z moim egzemplarzem?
- 13. Co jest nie tak z moim wyjątkiem?
- 14. Co jest nie tak z moim scala.swing?
- 15. Co jest nie tak z realloc?
- 16. Co jest nie tak w kodzie do
- 17. Deskryptory Fouriera Matlaba, co jest nie tak?
- 18. python 2.7/exec/co jest nie tak?
- 19. Co to jest kopia seryjna? I dlaczego jest tak zaimplementowany?
- 20. Jquery Tablesorter nie działa! Co z tym jest nie tak?
- 21. co jest nie tak z moją adnotacją @JsonCreator i MixIn?
- 22. Co jest nie tak z użyciem nowego miejsca docelowego []? do
- 23. Co jest nie tak z tym programem Clojure?
- 24. Co jest nie tak z tym routingiem Global.asax?
- 25. Co jest nie tak z przekazywaniem iteratora C++ przez odwołanie?
- 26. Co jest nie tak z debugowaniem w Eclipse na Androida?
- 27. C#/SQL - Co jest nie tak z SqlDbType.Xml w procedurach?
- 28. Wykonaj pętlę Next Run: Co jest nie tak z GCD?
- 29. Entity Framework 5.0. Co jest nie tak z moim zapytaniem?
- 30. Co jest nie tak z tym fragmentem kodu?
A co z małym opracowaniem :)? –
Wygląda na to, że taka asymetryczna równoważność byłaby użyteczna w paradygmacie OO, w taki sam sposób, że na poziomie typu 'ColoredPoint' jest - Point, ale nie na odwrót. Może nazwać to czymś innym niż "równa się" ... może "subEquals"? –
@LuigiPlinge być może 'canReplace',' zastępuje', 'określa' lub 'przesłonia' dla odwrotnej relacji? Wszystko dla wskazania '> =' -ness (lub '>:' jeśli chcesz) z tego. Wydaje mi się, że łatwiej mi to nazwać w kategoriach '> =' niż '<='. –