Mettre la méthode en trait ou, dans le cas de la classe?

Il y a deux façons de définir une méthode de deux classes différentes hériter de la même caractéristique dans le Scala.

sealed trait Z { def minus: String }
case class A() extends Z { def minus = "a" }
case class B() extends Z { def minus = "b" }

L'alternative est la suivante:

sealed trait Z { def minus: String = this match {
    case A() => "a"
    case B() => "b"
}
case class A() extends Z
case class B() extends Z

La première méthode répète le nom de la méthode, alors que la deuxième méthode répète le nom de la classe.

Je pense que la première méthode est la meilleure à utiliser, car les codes sont séparés. Cependant, je me suis trouvé souvent à l'aide de la seconde compliqué de méthodes, de sorte que l'ajout d'arguments supplémentaires peut être fait très facilement, par exemple comme ceci:

sealed trait Z {
  def minus(word: Boolean = false): String = this match {
    case A() => if(word) "ant" else "a"
    case B() => if(word) "boat" else "b"
}
case class A() extends Z
case class B() extends Z

Quelles sont les autres différences entre ces pratiques? Existe-il des bugs qui m'attendait si je choisis la deuxième approche?

EDIT:
J'ai été cité le ouvert/fermé principe, mais parfois, j'ai besoin de modifier non seulement la sortie de l'fonctions selon de nouvelles classes de cas, mais aussi l'entrée en raison de code refactoring. Est-il un meilleur modèle que le premier? Si je veux ajouter de la précédente fonctionnalités mentionnées dans le premier exemple, cela donnerait le laid code où l'entrée est répété:

sealed trait Z { def minus(word: Boolean): String  ; def minus = minus(false) }
case class A() extends Z { def minus(word: Boolean) = if(word) "ant" else "a" }
case class B() extends Z { def minus(word: Boolean) = if(word) "boat" else "b" }
  • Permettez-moi de spéculer que tout ajout non négligeable de la méthode de la classe de cas est malsain de OO point de vue. Cas instance de classe expose l'ensemble de ses entrailles, et les bons objets ne le sont pas. Il n'est donc pas un "vrai" objet, mais primitive semblables, comme string ou un tuple.