【版权声明】博客内容由厦门大学数据库实验室拥有版权,未经允许,请勿转载!
[返回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.