Passing parameters to a trait

You could use an abstract class

abstract class Piece(player: Int, pos: Pos) {
  ...
}

case class Pawn(player: Int, pos: Pos) extends Piece(player, pos)

Or (probably better) you define those members abstractly in a trait

trait Piece {
  def player: Int
  def pos: Pos
  ...
}

case class Pawn(player: Int, pos: Pos) extends Piece

I wasn't happy with the accepted answer for my use-case so I did the following. Note that you have two possibilities here for this same approach:

trait Piece {
   // these can be referred to within this trait to implement reusable code
   val player: Int 
   val pos: Pos

   def spaces(destination: Pos): List[Pos] = {
     // use player and pos at will e.g.
     List(pos, destination)  
   }
}

case class Pawn(playerArg: Int, posArg: Pos) extends Piece = {
   // now override those with whatever you like
   override val player: Int = playerArg 
   override val pos: Pos = posArg

   //some other code
}

The second alternative is to use and override methods instead e.g. def getPlayer: Int.

Yet another possibility is to use implicit on the trait methods that would require accessing those attributes but I'm not a big fan of this approach.

That said, apparently they have been thinking about it SIP-25 Trait Parameters.


Dotty allows traits to have parameters, just like classes have parameters.

trait Greeting(val name: String) {
  def msg = s"How are you, $name"
}

class C extends Greeting("Bob") {
  println(msg)
}

Tags:

Scala