【问题标题】:I am trying to initialise a Base Class property of a Sub Class but I am getting an error in Scala我正在尝试初始化子类的基类属性,但在 Scala 中出现错误
【发布时间】:2021-08-17 00:34:20
【问题描述】:

我试图让这个子类 Circle 继承父类 Shapes 的特征。我希望 Circle 类接受颜色字符串,但我不断收到错误消息。

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: 错误:覆盖 lang.this.String 类型的 Shape 类中的字段颜色;"

【问题讨论】:

  • 可变字段的一个案例类被设计破坏了,以后会给你带来麻烦。您想要做的更好的方法是像this (但是,返回当前类型通常有点复杂,请检查this

标签: scala inheritance multiple-inheritance


【解决方案1】:

在 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 中最惯用的。

【讨论】:

    【解决方案2】:

    您不能覆盖 var,但可以分配给它。

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

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

    【讨论】:

    • 我是编程新手,哪个变量是可变的?是 var 半径吗?如果可能的话,你能稍微详细一点吗?关于这个“可变变量很危险。假装 var 不存在”
    • 所有声明为var 的东西都是可变的。它的值可以改变。另一方面,val 是不可变的。它的值是固定的,永远不会改变。可以放心地引用它,因为它在此过程中没有被更改过。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-13
    • 2020-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多