java - Scala 构造函数混淆 - 请澄清

标签 java scala constructor

我对 Scala 的构造函数感到很困惑。例如,我有以下类表示一棵树,其中包含 Add 等运算符,树上的叶节点是数字。

abstract class Node(symbol: String) {}

abstract class Operator(symbol: String,
      binaryOp: (Double, Double) => Double ) extends Node(symbol) {
}

class Add(a: Number, b: Number) extends 
      Operator("+", (a: Double, b: Double) => a+b ) {
}

class Number(symbol: String) extends Node(symbol) {
    val value = symbol.toDouble
    def this(num: Double) {
      this(num.toString)
    }
}

我在一个网站上读到,Scala 构造函数中的内容自动不可变 (val),但 Stack Overflow 上的这个人说 "The input parameters for the constructor are not vals unless you say they are."所以这是一个矛盾。

此外,出于某种原因,我显然可能需要也可能不需要将“val”和“override”添加到构造函数中?我的意思是我希望一切都是公开的和不可变的,并且 Add 有一个等于“+”的符号,一个等于加法函数的 binaryOp,还有两个数字 a 和 b。有人可以用一种非冗长的方式解释如何让构造函数在 Scala 中按预期工作吗?

我希望能够做这样的事情:

addition = Add(Number(1), Number(2))
addition.binaryOp(addition.a.value, addition.b.value)

最佳答案

您几乎就在那里:Scala 类的构造函数的每个参数在构造类之后都会被丢弃,除非该类的方法使用它。在本例中,它是一个 private[this] val

但是,您可以简单地在构造函数参数前添加 val/var 关键字,它将成为公共(public) val/变量:

abstract class Node(val symbol: String) {}

通常,如果该字段已在父类(super class)中定义,则不会在子类的构造函数中重复此操作:

abstract class Operator(symbol: String, // no val here, only pass to super class
      val binaryOp: (Double, Double) => Double) extends Node(symbol) {
}

class Add(val a: Number, val b: Number) extends 
  Operator("+", (a: Double, b: Double) => a+b ) {
}

现在您可以从类外部访问这些字段:

addition = Add(Number(1), Number(2))
addition.binaryOp(addition.a.value, addition.b.value)

关于java - Scala 构造函数混淆 - 请澄清,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33228711/

相关文章:

c++ - 两个类的前向声明会导致构造函数中的循环依赖吗?

c# - 窗口关闭后无法设置可见性或调用 Show、ShowDialog 或 EnsureHandle

java - 使用 Spring Controller 返回的 jQuery 和 GSON 解析 JSON 对象

java - Scala Spring 检查空片段

scala - 混合面向对象和函数式编程

scala - Akka未加载application.conf

javascript - 为什么函数在构造函数中声明时不使用 new 关键字?

java - 设置android记事本教程项目时丢失文件

Java匹配字符串中的整个单词

java - 提供者 org.springframework.web.SpringServletContainerInitializer 不是子类型