3

継承されたトレイトで定義されたメソッドでサブタイプを強制するにはどうすればよいですか? ??? には何を入れますか?下

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)

 }
}

上記のコードは、(Organism,Organism) のタプルを返すため、 getOrganisms() メソッドを介して恐竜やアメーバを送信しても機能するはずです。

私が達成したい2つのコンセプトは次のとおりです。

  • アメーバはアメーバと交配する方法を知っており、ダイナソーはダイナソーと交配する方法を知っています。だから彼らに複雑な詳細を理解させてください。
  • 恐竜をアメーバに渡してはいけません。アメーバにはアメーバだけ
4

1 に答える 1

9

F-bounded polymorphism ( 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]whereXは、 でなければならないと述べていますOrganism[X]。これは、Xextends も持つ an のみを渡すことができることを意味します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: 具象インスタンスの戻り型を持つメソッドの実装

于 2013-04-17T19:56:32.160 に答える