从不相关的对象调用特征的超类方法

时间:2014-03-10 15:51:09

标签: scala inheritance reflection traits

目前我们有许多特征包含以下方法:

trait ThisTrait extends SuperTrait {
  override def getList: List[String] = 
    List(/* invariant list of strings */) ::: super.getList
}

其中“invariant”表示MyTrait的每个实例都具有相同的基本列表,同样SuperTrait的每个实例都具有相同的基本列表等。每次方法重新计算时都会浪费叫,所以我想将所有这些改为以下

trait ThisTrait extends SuperTrait {
  override def getList: List[String] = GetList.getList(super.getList)
}

// see edit below for a modified version of htis
private object GetList {
  private val baseList = (/* invariant list of strings */)
  private var thisList = null
  def getList(superList: List[String]) = {
    if(thisList == null) thisList = baseList ::: superList
    thisList
  }
}

这不是太糟糕了,因为super.getList也会返回一个(大部分)预先计算好的列表,不过我更喜欢我可以做以下的事情

private object GetList {
  private val thisList = (/* invariant list of strings */) ::: MyTrait.super.getList
  def getList = thisList
}

我可以通过MyTrait.getClass.getSuperclass.getMethod("getList")执行类似的操作,但我希望有一种类型安全的方法(除了硬编码对SuperTrait的{​​{1}}的引用} object)

编辑:我可以通过

改进这一点
GetList

所以我不会打电话给private object GetList { private val baseList = (/* invariant list of strings */) private var thisList = null def getList(superList: => List[String]) = { if(thisList == null) thisList = baseList ::: superList thisList } } ,除非需要它,但是我仍然有兴趣知道是否有一种类型安全的做法,如super.getList

1 个答案:

答案 0 :(得分:1)

不,这是件好事。如果可能,您可以在许多情况下破坏类不变量。我也非常确定如果你通过反射调用方法,你将获得与调用MyTrait的{​​{1}}相同的实现,以及无限循环。