Scala入门:特质(trait)

大数据学习路线图

【版权声明】博客内容由厦门大学数据库实验室拥有版权,未经允许,请勿转载!
[返回Spark教程首页]

Java中提供了接口,允许一个类实现任意数量的接口。在Scala中没有接口的概念,而是提供了“特质(trait)”,它不仅实现了接口的功能,还具备了很多其他的特性。Scala的特质,是代码重用的基本单元,可以同时拥有抽象方法和具体方法。Scala中,一个类只能继承自一个超类,却可以实现多个特质,从而重用特质中的方法和字段,实现了多重继承。

特质的定义

特质的定义和类的定义非常相似,有区别的是,特质定义使用关键字trait。

trait CarId{
  var id: Int
    def currentId(): Int     //定义了一个抽象方法
}

上面定义了一个特质,里面包含一个抽象字段id和抽象方法currentId。注意,抽象方法不需要使用abstract关键字,特质中没有方法体的方法,默认就是抽象方法。

把特质混入类中

特质定义好以后,就可以使用extends或with关键字把特质混入类中。

 class BYDCarId extends CarId{ //使用extends关键字
   override var id = 10000 //BYD汽车编号从10000开始
     def currentId(): Int = {id += 1; id} //返回汽车编号
 }
 class BMWCarId extends CarId{ //使用extends关键字
   override var id = 20000 //BMW汽车编号从20000开始
     def currentId(): Int = {id += 1; id} //返回汽车编号
 } 

下面,我们把上述代码放入一个完整的代码文件test.scala,编译运行。
请登录Linux系统,进入shell命令提示符状态,然后,输入以下命令进入“/usr/local/scala/mycode”目录,打开vim编辑器:

cd /usr/local/scala/mycode
vim test.scala

在test.scala文件中输入以下内容:

trait CarId{
  var id: Int
    def currentId(): Int     //定义了一个抽象方法
}
class BYDCarId extends CarId{ //使用extends关键字
   override var id = 10000 //BYD汽车编号从10000开始
     def currentId(): Int = {id += 1; id} //返回汽车编号
 }
 class BMWCarId extends CarId{ //使用extends关键字
   override var id = 20000 //BMW汽车编号从10000开始
     def currentId(): Int = {id += 1; id} //返回汽车编号
 } 
 object MyCar { 
    def main(args: Array[String]){
        val myCarId1 = new BYDCarId()       
        val myCarId2 = new BMWCarId()
        printf("My first CarId is %d.\n",myCarId1.currentId)
        printf("My second CarId is %d.\n",myCarId2.currentId)
    }
}

保存后退出vim编辑器。然后,使用scalac命令编译这个代码文件,并用scala命令执行,如下:

scalac test.scala
scala -classpath . MyCar //MyCar是代码中object后面的MyCar

上面命令执行后,会在屏幕输出以下结果:

My first CarId is 10001.
My second CarId is 20001.

特质可以包含具体实现

上面的实例中,特质只包含了抽象字段和抽象方法,相当于实现了类似Java接口的功能。实际上,特质也可以包含具体实现,也就是说,特质中的字段和方法不一定要是抽象的。

trait CarGreeting{
  def greeting(msg: String) {println(msg)}  
}

CarGreeting会把欢迎信息打印出来。

把多个特质混入类中

上面我们已经定义了两个特质,即CarId和CarGreeting。现在,我们可以把两个特质都混入到类中。
请登录Linux系统,进入shell命令提示符状态,然后,输入以下命令进入“/usr/local/scala/mycode”目录,打开vim编辑器:

cd /usr/local/scala/mycode
vim test.scala

在test.scala文件中输入以下内容:

trait CarId{
  var id: Int
    def currentId(): Int     //定义了一个抽象方法
}
trait CarGreeting{
  def greeting(msg: String) {println(msg)}  
}

class BYDCarId extends CarId with CarGreeting{ //使用extends关键字混入第1个特质,后面可以反复使用with关键字混入更多特质
   override var id = 10000 //BYD汽车编号从10000开始
     def currentId(): Int = {id += 1; id} //返回汽车编号
 }
 class BMWCarId extends CarId with CarGreeting{ //使用extends关键字混入第1个特质,后面可以反复使用with关键字混入更多特质
   override var id = 20000 //BMW汽车编号从10000开始
     def currentId(): Int = {id += 1; id} //返回汽车编号
 } 
 object MyCar { 
    def main(args: Array[String]){
        val myCarId1 = new BYDCarId()       
        val myCarId2 = new BMWCarId()
        myCarId1.greeting("Welcome my first car.")
        printf("My first CarId is %d.\n",myCarId1.currentId)        
        myCarId2.greeting("Welcome my second car.")
        printf("My second CarId is %d.\n",myCarId2.currentId)
    }
}

保存后退出vim编辑器。然后,使用scalac命令编译这个代码文件,并用scala命令执行,如下:

scalac test.scala
scala  -classpath . MyCar //MyCar是代码中object后面的MyCar

上面命令执行后,会在屏幕输出以下结果:

Welcome my first car.
My first CarId is 10001.
Welcome my second car.
My second CarId is 20001.

子雨大数据之Spark入门
扫一扫访问本博客