1

サブクラスがすべての初期化を完了した後、いくつかのコードを実行する必要があります。次に例を示します。

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

それを行う方法はありますか?

4

2 に答える 2

1

Bで遅延値を使用するか、「初期初期化子」を使用して、Bの値がAの値の前に初期化されるようにする必要があります。これら2つのオプションがどのように機能するかについての優れた説明は次のとおりです:https://github。 com / paulp / scala-faq / wiki/Initialization-注文

于 2012-04-28T16:27:17.877 に答える
0

だから私は答えを見つけたようです。私はDelayedInit特性アプローチを採用することにしました-遅延コードを実行し(そして実行された回数を数えます)、十分な初期化(拡張機能のクラスごとに1つ)が見られたと思ったら必要なコードを実行します階層)。私はそれを特性に包みました:

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
于 2012-04-29T06:32:29.857 に答える