Scala中的F绑定多态:具体子类未被识别为泛型类的子类型

时间:2013-10-23 15:43:21

标签: scala generics polymorphism

我有一个通用类型:

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方法的界面。

感谢。

1 个答案:

答案 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()