在Java中使用Scala特性和实现的方法
我想这是不可能调用从Java实现的Scala特性的方法,或者有办法吗?
假设我在Scala中:
trait Trait { def bar = {} } 在Java中如果我使用它
 class Foo implements Trait { } 
  Java抱怨Trait is not abstract and does not override abstract method bar() in Trait 
回答
 从Java的angular度来看, Trait.scala被编译到Trait 界面 。 因此,在Java中实现Trait被解释为实现一个接口 – 这使得你的错误信息变得明显。 简短的回答:你不能利用Java中的trait实现,因为这将启用Java中的多重inheritance(!) 
它在Scala中如何实现?
长的答案:那么它在Scala中如何工作? 查看生成的字节码/类可以find以下代码:
 interface Trait { void bar(); } abstract class Trait$class { public static void bar(Trait thiz) {/*trait implementation*/} } class Foo implements Trait { public void bar() { Trait$class.bar(this); //works because `this` implements Trait } } 
-   Trait是一个界面
-  抽象Trait$class(不要和Trait.class混淆)类是透明创build的,在技术上不会实现Trait接口。 然而,它确实有一个static bar()方法以Trait实例作为参数(sorting)
-   Foo实现了Trait界面
-   scalac通过委托给Trait$class自动实现Trait方法。 这基本上意味着调用Trait$class.bar(this)。
 请注意, Trait$class既不是Foo的成员,也不是Foo扩展。 它通过传递this简单的委托给它。 
混合在多个特征
继续关于Scala是如何工作的这个题外话……据说很容易想象如何在多种特质混合在一起工作:
 trait Trait1 {def ping(){}}; trait Trait2 {def pong(){}}; class Foo extends Trait1 with Trait2 
转化为:
 class Foo implements Trait1, Trait2 { public void ping() { Trait1$class.ping(this); //works because `this` implements Trait1 } public void pong() { Trait2$class.pong(this); //works because `this` implements Trait2 } } 
多重特性覆盖相同的方法
现在很容易想象如何混合多种特质,覆盖相同的方法:
 trait Trait {def bar(){}}; trait Trait1 extends Trait {override def bar(){}}; trait Trait2 extends Trait {override def bar(){}}; 
  Trait1和Trait2也将成为扩展Trait接口。 现在如果在定义Foo时Trait2最后一个: 
 class Foo extends Trait1 with Trait2 
你会得到:
 class Foo implements Trait1, Trait2 { public void bar() { Trait2$class.bar(this); //works because `this` implements Trait2 } } 
 但是,切换Trait1和Trait2 (使Trait1为最后)将导致: 
 class Foo implements Trait2, Trait1 { public void bar() { Trait1$class.bar(this); //works because `this` implements Trait1 } } 
可堆叠修改
现在考虑作为可堆叠修改的特性是如何工作的。 想象一下,有一个非常有用的类Foo:
 class Foo { def bar = "Foo" } 
你想用一些新的function来丰富你的特质:
 trait Trait1 extends Foo { abstract override def bar = super.bar + ", Trait1" } trait Trait2 extends Foo { abstract override def bar = super.bar + ", Trait2" } 
这是新的“Foo”类固醇:
 class FooOnSteroids extends Foo with Trait1 with Trait2 
它转化为:
Trait1
 interface Trait1 { String Trait1$$super$bar(); String bar(); } abstract class Trait1$class { public static String bar(Trait1 thiz) { // interface call Trait1$$super$bar() is possible // since FooOnSteroids implements Trait1 (see below) return thiz.Trait1$$super$bar() + ", Trait1"; } } 
Trait2
 public interface Trait2 { String Trait2$$super$bar(); String bar(); } public abstract class Trait2$class { public static String bar(Trait2 thiz) { // interface call Trait2$$super$bar() is possible // since FooOnSteroids implements Trait2 (see below) return thiz.Trait2$$super$bar() + ", Trait2"; } } 
FooOnSteroids
 class FooOnSteroids extends Foo implements Trait1, Trait2 { public final String Trait1$$super$bar() { // call superclass 'bar' method version return Foo.bar(); } public final String Trait2$$super$bar() { return Trait1$class.bar(this); } public String bar() { return Trait2$class.bar(this); } } 
所以整个堆栈的调用如下所示:
- FooOnSteroids实例(入口点)上的'bar'方法;
- Trait2 $ class的'bar'静态方法将此参数作为parameter passing,并返回'Trait2 $$ super $ bar()'方法调用和string“Trait2”的串联。
- 'Trait2 $$ super $ bar()'在FooOnSteroids实例调用…
- Trait1 $ class的'bar'静态方法将此参数作为parameter passing,并返回'Trait1 $$ super $ bar()'方法调用和string“Trait1”的串联。
- 调用FooOnSteroids实例的'Trait1 $$ super $ bar'…
- 原来的Foo的“酒吧”方法
结果是“Foo,Trait1,Trait2”。
结论
如果你已经设法阅读所有的东西,最初的问题的答案是前四行
 因为bar正在返回一个空Unit (一种NOP),所以确实不是抽象的。 尝试: 
 trait Trait { def bar: Unit } 
 然后bar会是一个返回void的Java抽象方法。