如何在继承的特征中定义的方法中强制执行子类型?我把什么放在???以下
trait Organism {
def reproduce(org:???):Bool
}
class Amoeba extends Organism {
def reproduce(org:Amoeba) = {// so cute..}
}
class Dinosaur extends Organism {
def reproduce(org:Dinosaur) = { // so scary}
}
我的客户端代码将类似于:
object BoozeParty {
def gonuts() = {
val (maleOrganism:Organism,femaleOrganism:Organism) = getOrganisms()
maleOrganism.reproduce(femaleOrganism)
}
}
以上代码应该有效,无论我通过getOrganisms()方法发送恐龙或变形虫,因为它返回(有机体,有机体)的元组
我想要实现的两个概念是:
答案 0 :(得分:8)
通常使用称为F-bounded多态的东西(参见Scala School)。
trait Organism[Self <: Organism[Self]] { self: Self =>
def reproduceWith(org:Self):Boolean
}
class Amoeba extends Organism[Amoeba] {
def reproduceWith(org:Amoeba) = ???
}
class Dinosaur extends Organism[Dinosaur] {
def reproduceWith(org:Dinosaur) = ???
}
class Monster extends Dinosaur
Organism[X]
其中X
表示必须是Organism[X]
。这意味着只能传递X
,并且还会扩展Organism[X]
。
为了防止Dinosaur extends Organism[Amoeba]
我添加了一个自我类型self: Self =>
,告诉编译器这个特性应该与传入的类型混合在一起。
mate
函数现在看起来像这样:
def mate[Species <: Organism[Species]](male:Species, female:Species) =
male reproduceWith female
用法是这样的:
val a1 = new Amoeba
val a2 = new Amoeba
val d1 = new Dinosaur
val d2 = new Monster
mate(a1, a2)
mate(d1, d2)
// wont compile
// mate(a1, d1)
如果您想要对类型进行更多限制(以及使用更复杂的代码),您可以查看以下答案:Scala: implementing method with return type of concrete instance