我正在尝试初始化 Sub Class 的 Base Class 属性 但我在 Scala 中遇到错误

I am trying to initialise a Base Class property of a Sub Class but I am getting an error in Scala

我正在尝试让这个 Sub Class Circle 继承父 class Shapes 的特征。我希望 Circle Class 接受颜色字符串,但我一直收到错误。

abstract class Shape  {
 def getArea():Double 
 var colour = "Red"

 def getColour():String = colour
 def setColour(newColour:String) = {
   colour = newColour 

 }
}

case class Circle (var radius:Int, override var colour:String) extends Shape {
  override def getArea():Double = 3.14 * radius * radius 
}

我得到的错误是:

"ScalaFiddle.scala:13: 错误:覆盖 class 形状 lang.this.String;"

中的字段颜色

您无法覆盖 var,但可以对其进行赋值。

case class Circle (var radius:Int, clr:String) extends Shape {
  colour = clr
  ...

顺便说一句,可变变量很危险。假装 var 不存在。没有它你会写出更好的代码。

在 Scala 中,方法通常被覆盖,而不是变量。默认情况下,Scala 不允许使用 vars(为什么?here a simple and brief explanation)。

  • 选项 1:

如果您想强制编译器允许,那么您必须为 Scala 编译器提供选项 -Yoverride-vars。通过该选项,您的代码应该可以正确编译和运行。

  • 选项 2:

有个技巧:让抽象变量保持未初始化状态。

示例:

sealed trait Shape {
  var colour: String
  def getColour: String = colour
  def setColour(colour: String): Unit = {
    this.colour = colour
  }
  def area: Double
}

case class Circle(radius: Int, var colour: String) extends Shape {
  override def area: Double = 3.14 * radius * radius
}

我知道,这段代码运行起来很奇怪。

  • 选项 3:

一种不需要特殊编译器选项并保持代码不可变的更惯用的方法:

sealed trait Shape {
  def colour: String
  def area: Double
}

case class Circle(radius: Int, colour: String) extends Shape {
  override def area: Double = 3.14 * radius * radius
}

你可以这样使用形状:

object Run extends App {
  val circle = Circle(10, "red")

  println(s"Circle area: ${circle.area}")
  println(s"Circle colour: ${circle.colour}")
  val circle2 = circle.copy(colour = "blue")
  println(s"Circle colour: ${circle2.colour}")
}

它将打印:

Circle area: 314.0
Circle colour: red
Circle colour: blue

#3 是 Scala 中最惯用的。