scala: как обернуть выполнение конструктора подкласса? - PullRequest
4 голосов
/ 21 мая 2011

в Scala, у меня есть базовый класс и несколько дочерних классов. без добавления кода в дочерний класс или изменения экземпляра дочернего класса я бы хотел, чтобы базовый класс мог вызывать некоторый код как до, так и после выполнения дочернего конструктора. before легко, так как конструктор базового класса вызывается до потомка, но я не вижу способа справиться с последующим регистром. в качестве примера кода:

class A {
  // do some stuff before child constructor is called
  // ...

  // do some other stuff after child constructor is called
  // this could be a method or inline in the constructor, doesn't matter.
}    

class B extends A { // stuff happens in between }

class C extends A { // stuff happens in between }
etc 

val b = new B // everything happens inside, no other method call needed

возможно ли такое поведение? спасибо.

Ответы [ 2 ]

4 голосов
/ 21 мая 2011

Если вы используете Scala 2.9, вы можете организовать что-то вроде этого:

class A { 
  println("Hi")
}
class B extends A with DelayedInit {
  private[this] var count = 0
  println("Hey")
  def delayedInit(x: => Unit) {
    x
    count += 1
    if (count==2) { println("There") }
  }
}
class C extends B { println("Ho") }
class D extends C { println("Ha") }

Это использует новую черту DelayedInit, которая отправляет отложенные конструкторы из текущего и всех дочерних классов в метод delayedInit. К сожалению, поскольку нет сигнала завершения, вы ограничены пропуском одного конструктора. Таким образом, для C мы получаем:

scala> new C
Hi
Hey
Ho
There

, где блок "Там" волшебным образом появился после блока "Ho" из C. К сожалению, если вы расширите C, новая инициализация произойдет последней:

scala> new D
Hi
Hey
Ho
There
Ha

(Вам на самом деле не нужен A там ... Я просто положил его туда, чтобы проиллюстрировать, что происходит с суперклассами.)

0 голосов
/ 07 июня 2011

Возможен обратный вызов «конец конкретного класса», код ниже выводит:

hello
world1
world2
world3
end of the worlds !

trait A extends DelayedInit {

  def delayedInit(body: => Unit) = {
    body
    println("end of the worlds !")
  }
}

trait B extends A { println("hello") }
trait C extends B { println("world1") }
trait D extends C { println("world2") }

object Zozo extends  D {
  println("world3")
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...