将参数传递给特征

时间:2016-08-17 10:23:24

标签: scala

我想模拟国际象棋游戏。 为此,我想创建一个抽象类Piece,它将一个玩家和一个位置作为参数。从那以后,我想扩展到其他类,例如Pawn

trait Piece(player: Int, pos: Pos) = {

  def spaces(destination: Pos): List[Pos]

}

case class Pawn extends Piece = {
//some other code
}

但是,我认为我不允许将参数传递给特征,例如trait Piece(player: Int, pos: Pos)

那我怎么能有一个有字段的抽象类Piece

3 个答案:

答案 0 :(得分:18)

您可以使用抽象类

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

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

或者(可能更好)您在特征中抽象地定义这些成员

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

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

答案 1 :(得分:5)

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)
}

答案 2 :(得分:0)

我对用例的可接受答案不满意,所以我做了以下工作。请注意,在这里使用相同的方法有两种可能性:

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
}

第二种选择是使用和覆盖方法,例如def getPlayer: Int

另一种可能性是在需要访问这些属性的特征方法上使用implicit,但我不是这种方法的忠实拥护者。

话虽如此,显然他们一直在思考SIP-25 Trait Parameters