我想模拟国际象棋游戏。
为此,我想创建一个抽象类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
?
答案 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。