Tuesday 29 May 2018

Self Type

Self type is a way to tell trait that it depends on another trait. We can achieve dependency injection of trait using self type

trait Targaryen {
  val name = "The House Targaryen"
}

tait History {
  this: Targaryen => // We are saying here History depends/required Targaryen
  def history : Unit = {
     println(s"$name ruled royal House of the Seven Kingdoms for three centuries")
  }
}

object GameOfThrones extends History with  Targaryen { //We mixed Targaryen because History required it
  def main(args: Array[String]): Unit = {
    GameOfThrones.history //The House Targaryen ruled royal House of the Seven Kingdoms for three centuries
  }
}


In History trait, method history will get $name from trait Targaryen.

Self type is denoted by "=>", in History trait, it declared as "this: Targaryen =>", We can replace "this" with any other name.

However, It's convention in Scala to use this.

When we extend History trait, self type makes compulsion to provide trait implementation of Targaryen so we mixed Targaryen in GameOfThrones object.

Cake design pattern is depends on self type.

Another advantage is that, if some trait Daenerys extends trait Targaryen then we can mix it with History

trait  Daenerys extends  Targaryen {
    def dracarys  = "Breathe fire!"
}

object GameOfThrones extends History with  Daenerys {
  def main(args: Array[String]): Unit = {
   println(GameOfThrones.dracarys)
  }
}

No comments:

Post a Comment