11

Cay Horstmann 的《不耐烦的 Scala》中的一个非常简单的练习一直困扰着我。它是关于primary,auxiliarydefault primary构造函数的:

ex 5.10: 考虑类

class Employee(val name: String, var salary: Double) {
  def this() { this("John Q. Public", 0.0) }
}

重写它以使用显式字段和默认的主构造函数。

我不确定我应该做什么。你们中的一些人可以提出一个解决方案吗?

然而,尝试解决这个练习可能让我意识到一些我以前没有注意到的关于主构造函数和val字段的事情(如你所见,我不太确定):

如果我说一个val字段(如上面nameEmployee类)只能通过primary构造函数而不是一个来初始化,我是对的auxiliary吗?在后一种情况下,编译器会将其视为对val导致错误的字段的重新分配。

起初我认为val字段大致相当于java中的最终字段,期望在任何构造函数中首次分配它们是合法的,但似乎我错了。

我对可能只是一个疯狂的猜测不太满意,所以如果有人能给我关于这一点的更准确的信息,我将不胜感激。

4

2 回答 2

14

来自“Scala 编程,第 2 版”第 6.7 段:

在 Scala 中,每个辅助构造函数都必须调用与其第一个操作相同的类的另一个构造函数。这条规则的最终结果是 Scala 中的每个构造函数调用最终都会调用该类的主构造函数。因此,主构造函数是类的单一入口点。

所以初始化的所有数据都val必须在主构造函数中。

您的具有显式字段的类可能类似于:

class Employee(n: String = "John Q. Public", s: Double = 0.0) {
  val name = n
  var salary = s
}

或没有默认参数值:

class Employee(n: String, s: Double) {
  def this() = this("John Q. Public", 0.0)
  val name = n
  var salary = s
}
于 2012-05-03T07:27:22.080 回答
12

实际上,我想到的是一个没有参数的主构造函数的版本,如下所示:

class Employee {
  private var _name = "John Q. Public"
  var salary = 0.0
  def this(n: String, s: Double) { this(); _name = n; salary = s; }
  def name = _name      
}

显然,这不如在主构造函数中定义字段,这是我想要说明的一点。

于 2012-06-12T15:27:53.920 回答