在方法签名中允许子类型的特征 [英] Trait allowing subtype in method signature
问题描述
如何在继承特征中定义的方法中强制执行子类型?我在什么地方放?
trait生物体{
def reproduce(org:???):Bool
}
class Amoeba延伸生物{
def reproduce(org:Amoeba)= {//很可爱......}
}
class恐龙延伸生物{
def reproduce(org:Dinosaur)= {// so scary}
}
我的客户端代码将如下所示:
object BoozeParty {
def gonuts()= {
val(男性有机体:有机体,女性组织)上面的代码应该工作,不管我通过getOrganisms()方法发送恐龙或变形虫,因为它返回(有机体,有机体)的元组,
我想达到的两个概念是:A b $ b b
$ b
Amoeba知道如何与Amoeba和恐龙交配知道如何与恐龙交配
。因此,让他们弄清楚错综复杂的细节。
恐龙不应该传给变形虫。只有变形虫才能变形虫
解决方案请参阅 Scala School )。
trait生物体[Self< ;: Organism [Self]] {self:Self =>
def reproduceWith(org:Self):Boolean
}
class Amoeba extends Organism [Amoeba] {
def reproduceWith(org:Amoeba)= ???
}
class恐龙延伸生物体[恐龙] {
def reproduceWith(org:恐龙)= ???
class怪物延伸恐龙
生物体[X]
其中 X
表示它必须是生物体[X]
。这意味着只有一个 X
可以被传入,这也延伸了生物体[X]
。
为了防止恐龙延伸生物体[Amoeba]
我添加了一个自我类型 self:Self =>
告诉编译器这个特征应该和传入的类型混合在一起。
mate $ c
$ def $ ma $ [物种< ;:有机体[物种]](男性:物种,女性:种类)=
男性再生与女性
用法如下:
val a1 =新Amoeba
val a2 =新Amoeba
val d1 =新恐龙$ b $ (a1,a2)
mate(d1,d2)
//不会编译
// mate(a1,d1)b val d2 = new怪物
mate
如果您想更多地限制类型(以及更复杂的代码),您可以看看这个答案: Scala:使用具体实例的返回类型实现方法
How do I enforce subtype in a method defined in the inherited trait? What do I place in the ??? below
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}
}
My Client Code will be something like:
object BoozeParty {
def gonuts() = {
val (maleOrganism:Organism,femaleOrganism:Organism) = getOrganisms()
maleOrganism.reproduce(femaleOrganism)
}
}
The above code should work irrespective of me sending dinosaurs or amoebas via the method getOrganisms() as it returns a tuple of (Organism,Organism)
The two concepts that I want to achieve are:
- Amoeba knows how to mate with Amoeba and Dinosaur knows how to mate with Dinosaur. So let them figure out the intricate details.
- A dinosaur should not be passed to an amoeba. Only an amoeba to an amoeba
It's common to use something called F-bounded polymorphism (see 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]
where X
states that it must be an Organism[X]
. This means that only an X
can be passed in that also extends Organism[X]
.
To prevent Dinosaur extends Organism[Amoeba]
I have added a self type self: Self =>
that tells the compiler this trait should be mixed in with the type that was passed in.
The mate
function now looks like this:
def mate[Species <: Organism[Species]](male:Species, female:Species) =
male reproduceWith female
Usage is like this:
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)
If you want even more restriction on the types (and with that more complex code) you can take a look at this answer: Scala: implementing method with return type of concrete instance
这篇关于在方法签名中允许子类型的特征的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!