trait

import classes.Point
import traits.Iterator
import traits.IntIterator
import traits.Dog
import traits.Cat
import scala.collection.mutable.ArrayBuffer
import traits.Pet

object Scala {

  def main( args : Array[ String ] ) : Unit =
    {
      var it = new IntIterator( 10 );
      println( it.next() )
      println( it.next() )
      println( it.next() )
      println( it.next() )
      println( it.next() )

      val dog = new Dog( "Harry" )
      val cat = new Cat( "Sally" )

      val animals = ArrayBuffer.empty[ Pet ]
      animals.append( dog )
      animals.append( cat )
//注意这个pet.name,这个name是在trait里面声明的,实现者的构造函数上有一个一样的变量,给实现者的赋值,想当于给trait的赋值,那么到底创建了几个变量? animals.
foreach( pet => println( pet.name ) ) // Prints Harry Sally } }
package traits

/**
 * use generic
 */
trait Iterator[ A ] {
  def hasNext : Boolean;
  def next() : A;

}
package traits

class IntIterator( to : Int ) extends Iterator[ Int ] {
  private var current = 0;
  def hasNext : Boolean = {
    current < to
  }

  def next() : Int = {
    if ( hasNext ) {
      val t = current
      current += 1
      t
    }
    else {
      0

    }
  }
}

上面是带范型的,下面是正常常规的

package traits

trait Pet {

  ///下面这个是语法糖,下面这个变量真正空间开在实现者身上,这里没有开辟空间或者声明变量
  var name : String;
}

class Cat( var name : String ) extends Pet;
class Dog( var name : String ) extends Pet;

//上面同name的trait解析

看编译后的文件

bogon:traits caicai$ ls
Cat.class    Dog.class    Pet.class
bogon:traits caicai$ pwd
/Users/caicai/workspace/scala/HelloWorld/src/traits/traits

那就是被编译成了三个class

Pet.class源码,Pet是一个接口,有俩个方法,由下可见trait里面并没有name这个字段.

bogon:traits caicai$ javap -c Pet.class 
Compiled from "Pet.scala"
public interface traits.Pet {
  public abstract java.lang.String name();

  public abstract void name_$eq(java.lang.String);
}

Dog.class源码

public class traits.Dog implements traits.Pet {
  public java.lang.String name();
    Code:
       0: aload_0                            
       1: getfield      #15                 // Field name:Ljava/lang/String;加载变量
       4: areturn

  public void name_$eq(java.lang.String);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #15                 // Field name:Ljava/lang/String;
       5: return

  public traits.Dog(java.lang.String);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #15                 // Field name:Ljava/lang/String;
       5: aload_0
       6: invokespecial #24                 // Method java/lang/Object."<init>":()V
       9: return
}

那么可以知道.下面这个语法是一个糖衣.

      val dog = new Dog( "Harry" )
      val cat = new Cat( "Sally" )

      val animals = ArrayBuffer.empty[ Pet ]
      animals.append( dog )
      animals.append( cat )
      //注意这个pet.name,这个name是在trait里面声明的,实现者的构造函数上有一个一样的变量,只创建了一个变量
      animals.foreach( pet => println( pet.name ) ) // Prints Harry Sally
package traits;

import scala.reflect.ScalaSignature;

@ScalaSignature(bytes="060152A!01020113	31Ai\41303
	a0136:bSR34801A
040131a01CA04133305A!"A050213M3427
\1
05-A!AB!osJ+g
050216355	!!03022005	3101+32;	21E01!211A0502I	AA\1nKV	1030502257921Q#07	03-!i21a060603121	a0120:p_Rt24B0116	033101&/323fM&21A$0207'R2430N\41305iA0102C2001050307I21012102219fW.Z0%KF$"!	232105352123BA22	0521)f.33;	1725r2221!a01'05310120J31	213502!21!Q!
M	QA\1nK02BQ!13010502)
a01P5oSRtDCA26-!	i0101C0322Q0107103")
public class Dog
  implements Pet
{
  private String name;
  
  public Dog(String name) {}
  
  public void name_$eq(String x$1)
  {
    this.name = x$1;
  }
  
  public String name()
  {
    return this.name;
  }
}
原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/9388404.html