Jus*_*s12 59 java scala scala-java-interop
我想不可能从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
Tom*_*icz 131
从Java角度Trait.scala编译成Trait 接口.因此,Trait在Java中实现被解释为实现一个接口 - 这使您的错误消息显而易见.简短回答:您无法利用Java中的特征实现,因为这将在Java中实现多重继承(!)
答案很长:那么它如何在Scala中运行?查看生成的字节码/类,可以找到以下代码:
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)是透明创建的类,这在技术上没有不实现Trait接口.但是它确实有一个static bar()以Trait实例为参数的方法(有点this)Foo实现Trait接口scalacTrait通过委托自动实现方法Trait$class.这基本上意味着要求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.现在,如果Trait2在定义时最后Foo:
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"
}
您希望使用特征丰富一些新功能:
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
它转化为:
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";
  }
}
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";
  }
}
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);
  }      
}
所以整个堆栈调用如下:
结果是"Foo,Trait1,Trait2".
如果你已经设法阅读了所有内容,原始问题的答案就在前四行......