2

我有一组模型,每个模型都公开了一个 next(...) 方法,该方法将模型向前移动一个离散的步骤。每个 next() 方法都有一个由抽象类型 T 给出的参数。

我希望能够用另一个类包装每个模型,其中包装器还将继承类型 T (每个模型都不同),但提供额外的逻辑。通过让包装器也扩展模型,这将是微不足道的,但这对于我实际模型实现的内部逻辑是不可行的。

我的解决方案是使用如下类型的投影:

trait Model {
  type T // works fine when this is a concrete implementation, but then cannot be overridden
  def next(input : T) = println(input)
}

abstract class Parent {
  type S <: Model
  type T = S#T
  val model : S
  def next(input : T) = model.next(input) 
}

这会因编译器错误而失败:类型不匹配;找到:input.type(具有基础类型 Parent.this.T) 需要:Parent.this.model.T

请注意,在 Parent 的任何具体实现中,Parent.this.T 应该等于 Parent.this.model.T。

到目前为止,我的解决方法是放弃使用类型系统,而只为每个模型创建唯一的父类(即复制父可能公开的所有其他逻辑)。这样做的正确方法是什么?

4

1 回答 1

3

学分去@senia。设置type T = model.T工作得很好:

abstract class Parent {
  type S <: Model
  type T = model.T
  val model : S
  def next(input : T) = model.next(input) 
}

class SimpleParent[GT <: Model](val model: GT) extends Parent {
  type S = GT
}

trait StringModel extends Model { type T = String }
trait IntModel    extends Model { type T = Int }

object Test {
  new SimpleParent(new StringModel {})
  new SimpleParent(new IntModel {})
}

看看这里,看看为什么type T = S#T不起作用。(简短版:我们可以有但不具体,因此可能model.type <: S与不兼容)。S#TS#Tmodel.T

于 2013-05-09T21:56:29.150 回答