合并特质功能的惯用方法

时间:2016-04-12 21:29:50

标签: scala

假设我有以下内容:

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
    }
  }
}

现在,我想要做的是MyServiceStone类型WoodMyService.supports(service)如果{true将返回service {1}}可以是BlueGreen,但falseRed

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

显然上面会产生冲突,因为WoodStone都实现了相同的方法。我可以创建一个新的trait StoneAndWood,但这看起来不够优雅。是否有一种优雅的方式来合并这两个函数(基本上在它们之间放置一个布尔or?)。不同的班级设计会使这项任务更容易吗?

2 个答案:

答案 0 :(得分:1)

如果不支持该服务,让Material的每个子类调用其超类的supports方法怎么样?像这样:

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
 }
}

答案 1 :(得分:0)

你可以做这样的事情

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