如何在继承特征中定义的方法中强制执行子类型?我要在 ??? 中放置什么?下面
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() 方法发送恐龙还是变形虫,上面的代码都应该有效,因为它返回一个 (Organism,Organism) 元组
我想要实现的两个概念是:
- 阿米巴知道如何与阿米巴交配,恐龙也知道如何交配 与恐龙。所以让他们弄清楚复杂的细节。
- 恐龙不应该遗传给阿米巴原虫。只有阿米巴原虫对阿米巴原虫
最佳答案
通常使用称为 F 界多态性的东西(请参阅 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]
。这意味着只能传入一个扩展了 Organism[X]
的 X
。
为了防止Dinosaur extends Organism[Amoeba]
,我添加了一个 self 类型 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
关于scala - 允许方法签名中存在子类型的特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16068398/