如何定义具有子特征的特征,以便他们的方法只采用共享实现?

时间:2011-12-10 08:24:47

标签: scala

我的元问题是“如何清晰地问这个问题?”但也许一个例子可以让它更清晰:

trait Toolbox {
  trait Bolt
  trait Wrench {
    def tighten(b : Bolt) 
  }

  def getWrench : Wrench
  def getBolt : Bolt
}


object MetricToolbox extends Toolbox {
...
}

object EnglishToolbox extends Toolbox {
...
}

当然,公制扳手只能拧紧公制螺栓;同上英文工具箱中的工具。我的问题是,如何以类型安全的方式表达,以便不会编译:

MetricToolbox.getWrench tighten EnglishToolbox.getBolt

但以下将:

def doTighten(box : Toolbox) = box.getWrench tighten box.getBolt

我知道这是可能的,因为我听说Martin Odersky昨晚在Scala聚会上用自己的嘴说出来但是在那一刻,我的妻子打电话给我的牢房,我不得不赶紧离开房间。解释了如何。

编辑 didierd指出我的代码是按照书面编写的。他是对的 - 我对细节有点不清楚但确实如此。自然的反向问题是,我如何这样做?答案非常简单:把这些类放在与主要特征相同的水平上。

trait Nail
trait Hammer {
  def pound(n : Nail)
}

trait Toolbox {
  trait Bolt
  trait Wrench {
    def tighten(b : Bolt) 
  }

  def getWrench : Wrench
  def getBolt : Bolt
  def getNail : Nail
  def getHammer : Hammer
}

 MetricToolbox.getHammer pound EnglishToolbox.getNail // this DOES compile

1 个答案:

答案 0 :(得分:8)

如上所述,它已经有效了。由于BoltWrench嵌套在Toolbox内,因此Bolt的{​​{1}}类型意味着tighten这个确切工具箱的Bolt,而不是任何工具箱的Bolt。它们分别是someToolbox.Bolt,这意味着确切实例BoltsomeToolBox的{​​{1}},这意味着Toolbox#Bolt类型中定义的Bolt无论什么是insatance工具箱。所以Toolbox是所有Toolbox#Bolt的常见超类型。

此处x.Bolt没有限定条件意味着Boltthis.Bolt是封闭的工具箱。所以你不能混。