我需要在子类已完成所有初始化之后执行一些代码,例如:
abstract class A(a:String) {
var sum = 0
def add(n:Int) = { sum += n; sum }
def verify = if (sum > 10) () else throw new Exception
... initialize subclass ...
verify
}
class B extends A("In A") {
val smth = add(50)
// I want to avoid calling `verify` here
}
val b = new B
println(b.smth) // 50
有办法吗?
答案 0 :(得分:1)
你需要在B中使用延迟val,或者使用“早期初始化器”,以便在A中的val之前初始化B中的val。这里是对这两个选项如何工作的一个很好的描述:{{3 }}
答案 1 :(得分:0)
所以我似乎找到了答案。我决定使用DelayedInit特征方法 - 我只是执行延迟代码(并计算它执行的次数),然后当我认为我已经看到足够的初始化(扩展中的每个类一个)时执行所需的代码层次)。我将它包装成一个特性:
trait AfterInit extends DelayedInit {
def afterInit
private var initCount = 0
private def getInitNumber(clazz: Class[_]):Int =
if (clazz.getSuperclass == classOf[java.lang.Object]) 0 else getInitNumber(clazz.getSuperclass) + 1
final def delayedInit(x: => Unit) {
x
initCount += 1
if (getInitNumber(this.getClass) + 1 == initCount) afterInit
}
}
用法:
abstract class A(id:String) extends AfterInit {
var sum = 0
def add(n:Int) = { sum += n; sum }
def afterInit = if (sum > 10) () else throw new Exception
}
class B extends A("B") {
val add1 = add(50)
}
new B // no exception
class C extends A("C") {
val add2 = add(5)
}
new C // exception is thrown, since the `sum` was too small