Scala - 构造函数中无法识别方法
我正在尝试扩展 javax.swing.Timer,但它只有一个构造函数,即
Timer(int delay, ActionListener listener)
我不希望 Scala 中的子类在其构造函数中采用 Java ActionListener
。我在非常旧的线程中读到“没有办法直接调用超类构造函数;你必须传递你自己的类的主构造函数”,所以看起来我被困住了主构造函数中的 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
}
}
但是我收到编译错误 error: not find: valuepublish
...为什么?以及如何修复?
I'm trying to extend javax.swing.Timer, but it only has one constructor, which is
Timer(int delay, ActionListener listener)
I do not want my subclass in Scala to take a Java ActionListener
in its constructor. I read in a very old thread that "there is no way to call a superclass constructor directly; you have to pass by the primary constructor of your own class", so it looks like I'm stuck with the ActionListener
in the primary constructor. So I've added an auxiliary constructor thus:
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
}
}
However I get a compile error error: not found: value publish
... why? And how to fix?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这里实际上有两个问题:在构造函数完成之前,
publish
和outer
都将不可用。 Scala 似乎有一个规则,即在主构造函数完成之前,不能在辅助构造函数中引用 this 实例。例如,以下内容将无法编译:不使用辅助构造函数,而是在伴生对象上定义工厂方法怎么样?
请注意,
ret
的前向引用需要使用lazy val
而不仅仅是val
。大概是在构造函数返回之前才调用actionPerformed
,否则ret
将因无限递归而无效。There are actually two problems here: both
publish
andouter
will not be available until the constructor has completed. Scala seems to have a rule thatthis
instance cannot be referenced in an auxiliary constructor until the primary constructor has completed. For example, the following will fail to compile:Rather than an auxiliary constructor, how about defining a factory method on the companion object?
Note that the forward reference of
ret
requires the use of alazy val
instead of justval
. PresumablyactionPerformed
is not called until the constructor returns, otherwiseret
will be invalid due to infinite recursion.这是我在这种特殊情况下发现的一种解决方法:发送一个虚拟的 ActionListener,然后删除并替换为真实的 ActionListener。
编辑:另一个技巧:将主构造函数设置为私有,这样就不会错误地尝试使用您自己的 ActionListener 进行构造。
编辑 2:或者通过在签名中传递匿名 ActionListener 来完全避免辅助构造函数。
编辑 3 - 已解决! :我刚刚在Javadoc中读到传递给构造函数的ActionListener可以为null!所以我们真正需要的是:
Here's a workaround I found in this particular case: send a dummy ActionListener then remove and replace with the real one.
Edit: another trick: making the primary constructor
private
so that there's no opportunity to mistakenly try constructing with your ownActionListener
.Edit 2: or avoid the auxiliary constructor altogether by passing an anonymous ActionListener in the signature.
Edit 3 - solved! : I just read in the Javadoc that the ActionListener passed to the constructor can be null! So all we actually need is: