我有一组模型,每个模型都公开了一个下一个(...)方法,该方法通过一个离散步骤向前移动模型。每个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)
}
这会因编译器错误而失败:类型不匹配; found:input.type(底层类型为Parent.this.T)必需:Parent.this.model.T
请注意,在Parent的任何具体实现中,Parent.this.T应该等于Parent.this.model.T。
到目前为止,我的解决方法是放弃使用类型系统,只为每个模型创建唯一的父类(即复制父可能公开的所有其他逻辑)。这样做的正确方法是什么?
答案 0 :(得分: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 {})
}
查看here,了解type T = S#T
无效的原因。 (简短版本:我们可能model.type <: S
和S#T
不具体,因此S#T
可能与model.T
不兼容。