【发布时间】:2011-10-26 19:05:54
【问题描述】:
如果我有以下 Scala 类:
abstract class MyOrdered extends Ordered[MyOrdered] {
def id: Int
def compare(that : MyOrdered) : Int =
if (that==null) 1 else (id-that.id)
}
那么我只需要在Scala中定义id方法就可以得到一个具体的类。但是如果我尝试在 Java 中扩展它,编译器会说 Ordered 的所有具体方法都丢失了。那么,这是否意味着 Scala 编译器只是将 Ordered 的具体方法的实现放在具体的 Scala 类中?
这看起来很浪费,因为我可以有几十个具体的类实现 MyOrdered,而且它们都会得到相同代码的副本,而实际上直接将它放在基类 MyOrdered 中就足够了。此外,这使得创建对 Java 友好的 Scala API 变得非常困难。除了使用虚拟方法实现使类具体化之外,还有什么方法可以强制 Scala 编译器将方法定义放在它应该这样做的地方?
更有趣的是在 Scala trait 中声明一个具体的方法 final。在这种情况下,它仍然没有在扩展 trait 的抽象 Scala 类中实现,但它不能在扩展抽象 Scala 类的 Java 类中实现,因为它被标记为 final。这绝对是一个编译器错误。最终的抽象方法毫无意义,即使它们在 JVM 中是合法的,显然。
【问题讨论】:
-
编译器错误应报告给问题跟踪器,并带有显示问题的最少源代码示例。
-
是的,但我不会轻易报告错误,所以我希望先让一些人同意我的观点。毕竟我可能弄错了。
-
我很乐意帮助您验证它,但我不明白您所描述的问题。小型 Scala 代码示例 + 描述预期行为会有很大帮助。随意编辑您的问题。当涉及到扩展具有从 Java 实现的某些方法的特征时,最好的答案是:不要那样做。迟早会出问题的。原因是 Java 没有任何对应的 Scala 可以映射到,因此它执行了各种从 Java 角度来看令人困惑的技巧。
-
我认为最终特征方法的问题是 Eclipse 的“表示编译器”而不是 Scala 的问题。无论如何,既然“不支持”在 Java 中扩展 trait-with-code,那么如何处理“final”本质上是无关紧要的。