标签:scala
本文记录我对Scala语言Traits的一些理解。
Scala语言没有接口(Interface)的概念,取而代之的,是功能更加强大的Trait。因此,interface在Scala语言里并不是关键字,我们可以自由的使用它,如下面这段代码所示:
但是要注意,上面的代码虽然是合法的Scala代码,能编译出ScalaObject.class。但是如果想在Java里正常使用这个class的话,就会遇到问题。
如果一个Trait没有定义任何有具体实现的方法,那么它和接口是等价的。换句话说,如果一个Trait的所有方法(如果有的话)全都是抽象的,那么Scala会把它编译成Java接口。比如下面这个没有任何方法的TraitA:
会被编译成TraitA.class,分析class文件可以知道,它其实等价于下面的Marker接口:
public interface TraitA {
}再比如下面这个有两个抽象方法的TraitB:
会被编译为:
public interface TraitB {
public int m1();
public int m2(int arg);
}
以下面这个TraitC为例:
编译之后得到两个class文件:TraitC.class和TraitC$class.class。分析class文件可以知道,TraitC.class实际上是一个接口,如下所示:
public interface TraitC {
public int m3(int arg);
}方法实现在TraitC$class.class里,如下所示:
public abstract class TraitC$class {
public static int m3(TraitC t, int arg) {
return 1;
}
public static void $init$() {
//return;
}
}由此可知:
如果Trait定义了字段呢?比如下面这个TraitD:
编译之后,仍然会得到两个class文件,如下所示:
public interface TraitD {
public int f1();
public void f1_$eq(int i);
}
public abstract class TraitD$class {
public static void $init$(TraitD t) {
t.f1_$eq(1);
}
}
由此可知:
下面通过一个类来观察一下mix in上面提到的Traits之后,会发生什么:
下面是反编译之后的MyClass(Java)代码:
public class MixedIn implements TraitA, TraitB, TraitC, TraitD {
private int f1;
public int f1() {
return this.f1;
}
public void f1_$eq(int val) {
this.f1 = val;
}
public int m1() {
return 0;
}
public int m2(int arg) {
return arg;
}
public int m3(int arg) {
return TraitC$class.m3(this, arg);
}
}
解释如下:
标签:scala
原文地址:http://blog.csdn.net/zxhoo/article/details/40378191