2 votes

Scala : Une bonne façon d'étendre les traits "statiques".

J'ai un trait et des classes qui l'étendent. Le problème est que toutes les méthodes du trait doivent être implémentées statiquement, donc je les mets dans les objets compagnons correspondants. J'ai écrit quelque chose comme :

A.scala

trait A

C1.scala

class C1 extends A {
  override def F = C1.F
}
object C1 extends A {
  def F: String = ???
}

...

Comme la méthode F doit être implémenté deux fois, j'ai ajouté un trait d'accompagnement correspondant.

Maintenant, j'ai quelque chose comme :

A.scala

trait A

AC.scala

trait AC {
 def F: String
}

C1.scala

class C1 extends A {
}
object C1 extends AC {
  def F: String = ???
}

C2.scala

class C2 extends A {
}
object C2 extends AC {
  def F: String = ???
}

...

Je me sens un peu bizarre parce qu'il n'y a rien d'autre qu'un trait vide. A dans A.scala. Je me demande s'il y a une meilleure façon d'organiser les codes.

3voto

Andrey Tyukin Points 29032

Je pense que vous devriez d'abord vous demander si vous voulez vraiment des méthodes dans le trait A ou si vous pouvez le déplacer dans une classe de type (vous avez déjà un objet compagnon de toute façon). Le résultat ressemblera à une invocation de méthode ordinaire, mais toutes ces invocations passeront, par définition, par l'instance de la classe de type.


Ceci étant dit, si vous préférez "étendre"...

S'il y a plusieurs méthodes dans le trait A et qu'ils doivent tous être mis en œuvre dans l'objet compagnon, vous pouvez utiliser le modèle classique de POO suivant des collections Scala :

trait A[C <: A[C]] {
  self: C =>
  def companion: ACompanion[C]           // one abstract `def`
  def f(): String = companion.f()        // implemented once
}

trait ACompanion[C <: A[C]] {
  def f(): String
}

class C1 extends A[C1] {
  val companion = C1                     // one line per class `C_N`
}

object C1 extends ACompanion[C1] {
  def f() = "that's a C1"                // all actual implementation in companion
}

println(new C1().f())

L'idée est que dans le trait A les méthodes qui s'appuient sur le compagnon (telles que f ), sont déléguées à l companion (ainsi, ils sont définis une fois comme companion.f() ).

Dans les classes d'implémentation, il suffit de préciser ce que l'on doit faire dans le cadre de l'implémentation. companion est (une ligne par sous-classe).

Cela peut réduire la quantité de texte passe-partout s'il y a plusieurs classes comme C1 ... C_N et d'autres méthodes comme f .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X