在Scala中,能够继承辅助构造函数吗?

9 浏览
0 Comments

在Scala中,能够继承辅助构造函数吗?

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

我测试了这段代码,但是它报错了:

temp.scala:18: error: too many arguments for constructor Child: ()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类中,一切都解决了。

0
0 Comments

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

问题的出现原因:

您的子类构造函数没有参数,但您尝试使用一个参数实例化它!您需要在子类构造函数中声明一个参数,然后将其传递给父类,例如:

class Child(v:Int) extends Father(v) {
}
val a = new Child(42)

解决方法:

在子类的构造函数中声明一个参数,并将其传递给父类。这样就可以实例化子类对象了。

0
0 Comments

在Scala中,不可能继承辅助构造函数。这是因为在辅助构造函数中可以引入一个可能初始化或不初始化的可变变量"value",这可能导致许多问题。因此,Scala决定所有对象的创建都必须通过主构造函数来进行,以确保一致的初始化。

如果你想让"value"有一个默认值,你可以在Scala 2.8+中将它指定为默认参数:

abstract class Father(val value: Int = 0)

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

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

通过上述方式定义了Father之后,下面两种Child的定义都是有效的:

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))

0