是否可以在Scala中继承辅助构造函数?

时间:2010-09-25 12:20:16

标签: scala

我想知道是否可以在Scala中继承辅助构造函数?

我测试了这段代码,并抱怨

  

temp.scala:18:错误:构造函数的参数太多了:()this.Child

     

val a = new Child(42)

   ^
abstract class Father {
 var value: Int = 0

 protected def setValue(v: Int) = {
  value = v
 }

 protected def this(v: Int) = {
  this()
  setValue(v)
 }
}

class Child extends Father {
}

val a = new Child(42)

但是,如果我把

protected def this(v: Int) = {
    this()
    setValue(v)
}

在Child课程中,一切都很好。

2 个答案:

答案 0 :(得分:2)

绝对不是,你的例子说明了原因。您已经引入了一个可变变量value,可能会也可能不会被初始化 - 具体取决于所使用的确切构造函数。

这是许多问题的潜在来源,因此Scala决定所有对象创建最终应通过主构造函数进行定向,这样可确保一致的初始化。

如果您希望value具有默认值,则可以将其指定为默认参数(在2.8 +中):

abstract class Father(val value : Int = 0)

或者你可以使用auxiluary构造函数在Scala 2.7中实现相同的效果:

abstract class Father(val value : Int) {
  def this() = this(0)
}

在上述任一方式中定义Father时,以下儿童定义均有效:

class Child(v:Int) extends Father(v)

class Child extends Father()

如果你绝对必须,你也可以让value变成一个var,但我强烈反对。

如果value的语义意味着它不能被初始化,那么正确的Scala惯用语就是将其声明为Option[Int]

abstract class Father(val value : Option[Int] = Some(0))

答案 1 :(得分:1)

你的Child构造函数没有参数,你试图用一个参数进行实例化!您必须在Child构造函数中声明一个参数,然后将其传递给Father类,例如:

class Child(v:Int) extends Father(v) {
}

val a = new Child(42)