Scala:是否有可能在子类的构造函数中覆盖val?

时间:2014-01-03 05:18:46

标签: scala override

是否可以覆盖子类构造函数中的valdef?我想在子类的构造函数中将trait的成员或抽象类的成员初始化(或设置)为参数

以下是一个例子。

trait A {
  def memberDef: Int => String
  val memberVal: String
}

class B(
    override val memberDef: Int => String,
    override val memberVal: String)
  extends A {
  ...
}

此处,class B的{​​{1}}会覆盖memberDef的{​​{1}}和trait A的{​​{1}}覆盖memberDefclass B

编译时,没有错误。但是,我想知道这个实现中是否存在任何错误,或者是否有更好的实现。

2 个答案:

答案 0 :(得分:5)

我想使用早期初始化程序添加一个可能的解决方案:

class B(memberDefParam: Int => String, memberValParam: String) extends {
  val memberVal: String = memberValParam
} with A {
  val memberDef: Int => String = memberDefParam
}

我会用这个,因为Martin Odersky说如果你使用早期的初始化程序就可以获得圣杯--L3级:专家库设计师: http://www.scala-lang.org/old/node/8610

通过作为构造函数参数提供的函数覆盖公共方法对我来说根本不好看,但这是另一个故事。

答案 1 :(得分:3)

帖子标题的答案是肯定的。在大多数情况下。

很难说什么可能是“更好”的实现,因为我不知道你要用这​​个代码完成什么(除了概念证明)。但有两件事需要考虑。

您通常不希望其中包含val的特征。只有在特征级别使用lazy valdef才能解决棘手的,记录良好的初始化问题。此外,虽然特征中的def可以由defvallazy valobject实现,但特征中的val只能由val实施。因此,那里的灵活性要低得多。

要考虑的另一件事是关于Scala语法,但更一般的对象设计。我知道你的例子是人为的,但请记住,你通过给调用者改变B的公共API来创建漏洞抽象。漏洞抽象永远不会好。