在方法签名性状允许亚型(Trait allowing subtype in method signa

2019-08-31 09:54发布

如何执行亚型在遗传性状中定义的方法? 我怎么放置在??? 下面

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发送恐龙或变形虫(),因为它返回的元组(生物,生物)

我想实现的两个概念:

  • 变形虫知道如何与队友变形虫和恐龙知道如何与恐龙交配。 因此,让他们搞清楚复杂的细节。
  • 恐龙不应该传递给变形虫。 只有一个阿米巴变形虫

Answer 1:

这是通常使用一种叫做F-界多态性(见斯卡拉学校 )。

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)

如果你想要的类型更加限制(并与更复杂的代码),你可以看看这个答案: 斯卡拉:实现方法与具体实例的返回类型



文章来源: Trait allowing subtype in method signature