scala——trait

来源:互联网 发布:全国凤楼兼职信息源码 编辑:程序博客网 时间:2024/05/01 00:09
trait 可以理解为一个实现了函数体的接口,或者胖接口

每当一个trait被创建时
会生成以接口和一个辅助抽象类。所有的函数实现部分都作为静态函数写在辅助抽象类中。主函数中中所有的调用都会直接调用抽象类中的静态函数实现。


代码
trait solver{
  var value=1;
  def answer():Int
  def  show() = {println(answer())}
  def  showa(a :Int) = {println(println(a))}
}
class fang extends solver{
  override def answer()=42
}
 public void main(String[] args)
  {
    fang a = new fang();                                                                                       第一步
    a.show();                                                                                                          第二步
    a.showa(100);                                                                                                 第五步                                           
 }
编译后的内容 solver.class
public abstract interface solver  生成一个接口
{
  public abstract int value();
  public abstract void value_$eq(int paramInt);
  public abstract int answer();
  public abstract void show();
  public abstract void showa(int paramInt);
}

编译后的内容 solver$class.class  生成一个辅助抽象类
import scala.Predef.;
import scala.runtime.BoxedUnit;
import scala.runtime.BoxesRunTime;
public abstract class solver$class
{
 public static void show(solver $this)                                                                                    
  {Predef..MODULE$.println(BoxesRunTime.boxToInteger($this.answer())); }  第四步  输出42
   public static void showa(solver $this, int a) { Predef..MODULE$.println(BoxesRunTime.boxToInteger(a)); Predef..MODULE$.println(BoxedUnit.UNIT);                                                          第七部    输出100
  }
  public static void $init$(solver $this)
  {   $this.value_$eq(1);}
}

继承trait的类  fang.class
import scala.reflect.ScalaSignature;
import scala.runtime.TraitSetter;
public class fang implements solver
{
  private int value;
  public int value()
  {  return this.value; } 
  public void value_$eq(int x$1) { this.value = x$1; } 
  public void show() { solver.class.show(this); }                                第三步  调用最终的show函数
  public void showa(int a) { solver.class.showa(this, a); }                 第六步  调用最终的showa函数
  public int answer() { return 42; }
  public fang()
  {  solver.class.$init$(this);}
}


  
with trait
当用了with trait时,在实现的时候会在当前类的基础上,增加ExclamatoryGreeter$class.class中所有的函数,且函数名相同,但函数体不同。
那这些函数体怎么写呢。这些函数的函数体就是调用ExclamatoryGreeter$class.class中对应的真实函数。
所以当你调用greet这个函数时,其实你调用的是当前Dog类中新增的greet函数,然后这个greet函数内才真正调用ExclamatoryGreeter$class.class中的greet函数。

ExclamatoryGreeter定义:
trait   ExclamatoryGreeter{
def greet() = “Hi”
}

main函数中:
var pet = new Dog with ExclamatoryGreeter
println(pet.greet)

反编译之后Dog类
var pet = new Dog() { public String greet() { return ExclamatoryGreeter.class.greet(this); } };    增加了ExclamatoryGreeter中定义同名的函数,并条用同名原函数
混入多个with trait1 with trait2时
假如trait1 中有个put函数,trait2中也有个put函数。scala会默认重右边开始调用,它会先调用trait2中的put函数,然后在trait2中调用trait1中的put函数

主函数.class   反编译文件
BasicIntQueue queue = new BasicIntQueue() { 
     public void Incrementing$$super$put(int x) { Filtering.class.put(this, x); }         第四步
      public void put(int x) { Incrementing.class.put(this, x); }                                      第二步
      public void Filtering$$super$put(int x) { super.put(x); }                                      第六步

    };
Filtering$.class   反编译文件
  public static void put(Filtering $this, int x)
  {
    if (x >= 0) $this.Filtering$$super$put(x);                                                                 五步
  }
  
  Incrementing$.class   反编译文件
  public static void put(Incrementing $this, int x)
  {
    $this.Incrementing$$super$put(x + 1);                                                                     第三步
  }

主文件
new BasicIntQueue  with Filtering  with  Incrementing                                              第一步
queue.put(-1)
0 0
原创粉丝点击