Scala - 构造函数中无法识别的方法

Lui*_*hys 2 constructor scala

我正在尝试扩展javax.swing.Timer,但它只有一个构造函数,即

Timer(int delay, ActionListener listener) 
Run Code Online (Sandbox Code Playgroud)

我不希望Scala中的子类ActionListener在其构造函数中使用Java .我在一个非常古老的线程中读到"没有办法直接调用超类构造函数;你必须通过你自己的类的主要构造函数",所以它看起来像我ActionListener在主构造函数中被困住了.所以我添加了一个辅助构造函数:

case class TimerEvent (source: AnyRef) extends swing.event.Event

class ScalaTimer2 (delay: Int, listener: java.awt.event.ActionListener)
      extends javax.swing.Timer(delay, listener) with swing.Publisher {
  outer =>
  def this(delay: Int) = {
    this(delay, new java.awt.event.ActionListener {
      def actionPerformed(e: java.awt.event.ActionEvent) {
        publish(TimerEvent(outer))   // <-- publish not recogonized
      }
    })
//    publish(TimerEvent(outer)) // <-- publish recognized here
  }
}
Run Code Online (Sandbox Code Playgroud)

但是我得到了编译错误error: not found: value publish......为什么?以及如何解决?

Kip*_*ros 5

这里实际上有两个问题:既publishouter之前的构造已完成将不可用.Scala似乎有一个规则,即this在主构造函数完成之前,实例不能在辅助构造函数中引用.例如,以下将无法编译:

class Foo (x: Unit) { def this() { this(println(this)) } }
Run Code Online (Sandbox Code Playgroud)

而不是辅助构造函数,如何在伴随对象上定义工厂方法?

object ScalaTimer2 {
  def apply(delay: Int): ScalaTimer2 = {
    lazy val ret: ScalaTimer2 = new ScalaTimer2(delay, new java.awt.event.ActionListener {
      def actionPerformed(e: java.awt.event.ActionEvent) {
        ret.publish(TimerEvent(ret))
      }
    })
    ret
  }
}
Run Code Online (Sandbox Code Playgroud)

注意,前向引用ret需要使用a lazy val而不是just val.据推测actionPerformed,在构造函数返回之前不会调用,否则ret由于无限递归而无效.