如何在Scala中“覆盖”内部类?

9
在Enumeration#Val类的Scaladoc中,我可以看到:“实现Value类型的类。可以重写此类以更改枚举的命名和整数标识行为。”我感到困惑:如何覆盖一个类?像override class Val extends super.Val这样的东西是不被允许的。

object MyEnum extends Enumeration中,可以定义一个内部类,例如:class Val(i: Int, name: String) extends super.Val(i, name),但它几乎不会覆盖Enumeration#Val,因为它根本没有被实例化。 - Jean-Philippe Pellet
1个回答

12
Scala目前没有虚拟类,因此您无法编写 `override class Val ...`,并确保调用 `new Val` 会动态地为新实例选择正确的类。相反,将根据对封闭类实例的引用的类型(在本例中为 `Enumeration`)选择类。
模拟虚拟类的一般技巧是编写 `class Val extends super.Val`,然后覆盖作为类实例工厂的受保护方法。在这种情况下,您还必须覆盖该方法:
protected def Value(i: Int, name: String): Value = new Val(i, name)

Enumeration将仅使用此工厂方法创建Val实例。通常,这种模式需要程序员的自律,但可以通过将构造函数声明为私有来确保,从而强制程序员使用工厂方法。


谢谢您的解释。现在我更加好奇如何覆盖一个final方法... - Jean-Philippe Pellet
(仅供其他读者解释:您提到的方法实际上在Enumeration.scala中是final的。)顺便说一下,您写道“Scala中没有虚拟类(但可能会有)”。有证据表明这可能在未来出现吗? - Jean-Philippe Pellet
这个问题已经讨论了相当长的时间。我认为它们在未来是计划中的,但我不认为有人知道具体什么时候会发生。http://scala-programming-language.1934581.n4.nabble.com/scala-when-will-Scala-get-virtual-class-support-td2002555.html,https://dev59.com/MnA75IYBdhLWcg3w6Nr8 - axel22
你不能覆盖 Value 方法,因为它是 final 的。 - Thayne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接