简体   繁体   English

Scala中带有构造函数参数的抽象类

[英]Abstract classes with constructor parameters in Scala

I have the following class model: 我有以下类模型:

sealed abstract class Tile(val coordinate: Int, val isOccupied: Boolean) {
  def isEmpty() : Boolean
  def getPiece() : Option[Piece]
}

case class EmptyTile(coordinate: Int) extends Tile(coordinate, false) {
  override def toString: String = "" +coordinate
  override def isEmpty() = true
  override def getPiece() = None
}

case class OccupiedTile(coordinate: Int, val piece: Piece) extends Tile(coordinate, true) {
  override def toString = piece.toString
  override def isEmpty = false
  override def getPiece = Some(piece)
}

and I get the following error: 我收到以下错误:

Error:(6, 22) overriding value coordinate in class Tile of type Int;
 value coordinate needs `override' modifier
case class EmptyTile(coordinate: Int) extends Tile(coordinate, false) {
                 ^

What am I doing wrong? 我究竟做错了什么?

EDIT: Request to see Piece class, adding here: 编辑:请求查看Piece类,在此处添加:

import Alliance.Alliance
import PieceType.PieceType

abstract class Piece(val piecePosition: Int, val pieceType : PieceType, val alliance: Alliance) extends Movable {
}

object PieceType extends Enumeration {
  type PieceType = Value
  val PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING = Value
}

Your abstract class Tile declares a val coordinate , making this value publicly accessible. 您的抽象类Tile声明了一个val coordinate ,使该值可公开访问。 Your case class EmptyTile implicitly declares coordinate as a val as well (case class "magic"). 你的case类EmptyTile隐式地将coordinate声明为val(case class“magic”)。 Basically, your case class is effectively trying to override a value already provided by your abstract class. 基本上,您的case类有效地尝试覆盖抽象类已经提供的值。

You can either remove the val in your abstract class declaration, or not make EmptyTile and OccupiedTile case classes. 您可以删除抽象类声明中的val ,也可以不删除EmptyTileOccupiedTile案例类。

Edit: proposed alternative after comment: 编辑:评论后建议的备选方案:

trait Tile {
  def coordinate: Int
  def isOccupied: Boolean
  def isEmpty() : Boolean = !isOccupied
  def getPiece() : Option[Piece]
}

case class EmptyTile(coordinate: Int) extends Tile {
  override def toString: String = "" +coordinate
  val isOccupied = false
  def getPiece() = None
}

case class OccupiedTile(coordinate: Int, val piece: Piece) extends Tile {
  override def toString = piece.toString
  val isOccupied = true
  def getPiece = Some(piece)
}

case class automatically makes its arguments val s. case class自动使其参数为val This is why the argument coordinate to EmptyTile , understood as val coordinate , conflicts with the abstract class's val coordinate . 这就是为什么与EmptyTile coordinate的参数(理解为val coordinate )与抽象类的val coordinate冲突。

One way to fix this is to have coordinate and isOccupied be defined as abstract in Tile . 解决这个问题的一种方法是在Tile isOccupied coordinateisOccupied定义为abstract。 Tile can even be a trait instead of an abstract class: Tile甚至可以是一个特征而不是一个抽象类:

sealed trait Tile {
  def coordinate: Int
  def isOccupied: Boolean
  ...
}

case class EmptyTile(coordinate: Int) extends Tile {
  def isOccupied = false
  ...
}

case class OccupiedTile(coordinate: Int, piece: Piece) extends Tile {
  def isOccupied = true
  ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM