web-dev-qa-db-fra.com

Quelles sont les différences entre la classe finale et la classe scellée à Scala?

Il existe deux types de modificateurs dans Scala: final et sealed

Quelles sont les différences entre eux? Quand devriez-vous utiliser l'un sur l'autre?

48
user1187135

Une classe final ne peut pas être étendue, point.

Un trait sealed ne peut être étendu que dans le même fichier source qu'il est déclaré. Ceci est utile pour créer des ADT (types de données algébriques). Un ADT est défini par la somme de ses types dérivés.

Par exemple.:

  • Un Option[A] est défini par Some[A] + None.
  • UNE List[A] est défini par :: + Nil.

sealed trait Option[+A]

final case class Some[+A] extends Option[A]
object None extends Option[Nothing]

Car Option[A] est scellé, il ne peut pas être étendu par d'autres développeurs - cela changerait son sens.

Some[A] est définitif car il ne peut pas être prolongé, point final.


En prime, si un trait est scellé, le compilateur peut vous avertir si vos correspondances de motifs ne sont pas assez exhaustives car sait que Option est limité à Some et None.

opt match {
    case Some(a) => "hello"
}

Attention: la correspondance peut ne pas être exhaustive. Il échouerait sur l'entrée suivante: None

88
dcastro

sealed classes (ou traits) peuvent toujours être héritées dans le même fichier source (où final classes ne peuvent pas être héritées du tout).

Utilisez sealed lorsque vous souhaitez restreindre le nombre de sous-classes d'une classe de base (voir "Type de données algébrique").

Comme l'un des avantages très pratiques d'une telle restriction, le compilateur peut maintenant vous avertir des correspondances de modèle non exaustives:

sealed trait Duo
case class One(i:Int) extends Duo
case class Two(i:Int, j:Int) extends Duo

def test(d:Duo) {
  match {
    case One(x) => println(x) // warning since you are not matching Two
  }
}
8
agschaid