web-dev-qa-db-fra.com

Quel est le problème de l'héritage de classe de cas * so *?

Tout en cherchant autre chose, tout à fait par pure coïncidence, je suis tombé sur quelques commentaires sur la façon dont l'héritage de classe de cas diabolique est. Il y avait cette chose appelée ProductN, misérables et rois, elfes et sorciers et comment une sorte de propriété très souhaitable est perdue avec l'héritage des classes de cas. Alors, quel est le problème avec l'héritage de classe de cas?

66
Ashkan Kh. Nazary

Un mot: égalité

Les classes case sont livrées avec une implémentation fournie de equals et hashCode. La relation d'équivalence, connue sous le nom de equals fonctionne comme ceci (c'est-à-dire doit avoir les propriétés suivantes):

  1. Pour tous x; x equals x est true (réflexif)
  2. Pour x, y, z; si x equals y et y equals z puis x equals z (transitif)
  3. Pour x, y; si x equals y puis y equals x (symétrique)

Dès que vous autorisez l'égalité au sein d'une hiérarchie d'héritage, vous pouvez casser 2 et 3. cela est trivialement démontré par l'exemple suivant:

case class Point(x: Int, y: Int)
case class ColoredPoint(x: Int, y: Int, c: Color) extends Point(x, y) 

Ensuite nous avons:

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

Mais pas

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

Vous pourriez faire valoir que toutes les hiérarchies de classes peuvent avoir ce problème, et c'est vrai. Mais les classes de cas existent spécifiquement pour simplifier l'égalité du point de vue d'un développeur (entre autres raisons), donc les faire se comporter de manière non intuitive serait la définition d'un objectif propre!


Il y avait aussi d'autres raisons; notamment le fait que copy n'a pas fonctionné comme prév et interaction avec le filtreur de motifs .

109
oxbow_lakes