3 votes

Voie idiomatique pour fusionner la fonctionnalité du trait

Supposons que j'ai ce qui suit :

abstract class Service {}
case class Blue() extends Service
case class Green() extends Service
case class Red() extends Service

abstract trait Material {
  def supports(s: Service): Service
}

trait Wood extends Material {
  def supports(s: Service): Boolean = {
    s match {
      case _:Blue => false
      case _:Green => true
      case _ => false
    }
  }
}

trait Stone extends Material {
  def supports(s: Service): Boolean = {
    s match {
      case _:Blue => true
      case _:Green => false
      case _ => false
    }
  }
}

Maintenant, ce que je veux faire est d'avoir un type MyService qui est à la fois Stone et Wood, de sorte que MyService.supports(service) renverra true si service est soit Blue soit Green, mais false s'il s'agit de Red :

case class MyService() extends Wood with Stone
service = new MyService()
service.supports(new Blue()) //true
service.supports(new Green()) //true
service.supports(new Red()) //false

Évidemment, ce qui précède crée un conflit car à la fois Wood et Stone implémentent la même méthode. Je pourrais créer un nouveau trait StoneAndWood, mais cela semble peu élégant. Existe-t-il un moyen élégant de fusionner ces deux fonctions (mettre essentiellement un or booléen entre elles) ? Une conception de classe différente faciliterait-elle cette tâche ?

1voto

Pillsy Points 7094

Que diriez-vous si chaque sous-classe de Material appelait la méthode supports de sa superclasse si elle ne prend pas en charge le service ? Quelque chose comme ceci :

abstract trait Material {
  def supports (s: Service) = false
}

trait Wood extends Material {
  override def supports (s: Service) = 
    s match { 
      case _: Green => True; 
      case _       => super supports s
    }
}

trait Stone extends Material {
  override def supports (s: Service) = 
    s match { 
      case _: Blue => True; 
      case _       => super supports s
    }
}

0voto

Gustek Points 2006

Vous pouvez faire quelque chose comme ça

class WoodStone extends Wood with Stone {
  override def supports(s: Service): Boolean = {
    super[Wood].supports(s) || super[Stone].supports(s)
  }
}

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