我经常遇到一个问题,我需要一个抽象类的实现中的成员来表示它将返回具体类型。我确定我这里缺少明显的东西。
这是一个说明问题的简单示例:
object Poop {
def getValue[T <: Poop](x: T): T = x.aValue
}
abstract class Poop {
val aValue: Poop
}
这显然无法使用“类型为Poop的表达式不符合预期的类型T”来编译x.aValue表达式,这显然是因为编译器不知道aValue的实际类型是什么。
如何定义我的抽象类,以便aValue将成为具体类型?还是应该像这样对问题建模?
答案 0 :(得分:4)
这可以通过F-bounded polymorphism来实现:
object Poop {
def getValue[T <: Poop[T]](x: T): T = x.aValue
}
abstract class Poop[Self <: Poop[Self]] {
val aValue: Self
// No need for an external method. This will return the concrete type.
def getValue: Self = aValue
}
class Foo extends Poop[Foo] {
val aValue: Foo = this
}
让抽象类带有类型参数并不总是很方便。在这种情况下,可以将具体类型定义为类型成员:
object Poop {
// Helper type that provides access to the concrete type with a type parameter.
type Aux[C <: Poop] = Poop { type Self = C }
def getValue[T <: Poop.Aux[T]](x: T): T = x.aValue
}
abstract class Poop {
type Self <: Poop.Aux[Self]
val aValue: Self
def getValue: Self = aValue
}
class Foo extends Poop {
type Self = Foo
val aValue: Foo = this
}