我有一个通用类型:
trait BaseTrait[T <: BaseTrait[T]] {
self: T =>
def similar(that: T): Float
}
具体类型:
class MyConcrete(val..) extends BaseTrait[MyConcrete] {
type Self = MyConcrete
..
def similar(that: MyConcrete) = {
return 0.5f // dummy
}
}
我想写这样的东西:
def create[T <: BaseTrait[T]](..): T = new MyConcrete(..)
我收到错误:
type mismatch; found: MyConcrete required: T
我期待由于MyConcrete是BaseTrait的子类型,它会起作用(但我错了)
我的意图是隐藏MyConcrete的构造,以便稍后我可以将上面的内容更改为MyConcrete2(它也像MyConcrete一样扩展BaseTrait),我的代码只关心BaseTrait接口,不会受到我的更改的影响。
如何编写create方法的界面。
感谢。
答案 0 :(得分:1)
def create[T <: BaseTrait[T]](..): T = new MyConcrete(..)
该类型参数T
没有多大意义。您要求调用者告诉方法T
是什么,这在这种情况下显然不起作用。如果你将T
解释为从方法中返回的东西(自动推断),那么调用者仍然无法用它做很多事情。
从来电者的角度来看,你能得到的最好的是
def create(..): BaseTrait[_] = new MyConcrete(..)
另一方面,如果您想要一个特定的子类型但隐藏MyConcrete
的实现,您将定义一个特征
trait ConcreteLike extends BaseTrait[ConcreteLike]
class MyConcrete extends ConcreteLike {
def similar(that: ConcreteLike) = 0.5f
}
def create(): ConcreteLike = new MyConcrete()