RAbraham
RAbraham

Reputation: 6324

Trait allowing subtype in method signature

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:

Upvotes: 4

Views: 1969

Answers (1)

EECOLOR
EECOLOR

Reputation: 11244

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

Upvotes: 10

Related Questions