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="