是否可以覆盖子类构造函数中的val
或def
?我想在子类的构造函数中将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}}覆盖memberDef
是class B
。
编译时,没有错误。但是,我想知道这个实现中是否存在任何错误,或者是否有更好的实现。
答案 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 val
或def
才能解决棘手的,记录良好的初始化问题。此外,虽然特征中的def
可以由def
,val
,lazy val
或object
实现,但特征中的val
只能由val
实施。因此,那里的灵活性要低得多。
要考虑的另一件事是关于Scala语法,但更一般的对象设计。我知道你的例子是人为的,但请记住,你通过给调用者改变B
的公共API来创建漏洞抽象。漏洞抽象永远不会好。