scala中的构造函数(主要/辅助/默认主要)

时间:2012-05-03 06:20:50

标签: scala constructor

来自 Cay Horstmann的 «Scala for the impatient»的一个非常简单的练习让我感到困惑。这是关于primaryauxiliarydefault primary构造函数:

  

ex 5.10:   考虑班级

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

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

我不确定我应该这样做。你们有些人可以提出解决方案吗?

然而,试图解决这个练习可能让我意识到我之前没有注意到关于主构造函数和val字段的东西(你可以看到,我不太确定):

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

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

我对这可能只是一个疯狂的猜测并不十分满意,所以如果有人能给我更准确的信息,我会很感激。

2 个答案:

答案 0 :(得分:13)

来自“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
}

答案 1 :(得分:11)

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

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      
}

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