特质
1、java中多实现的表达是通过接口,scala中用特质来代替接口。也就是说,多个类具有相同的特质(特征)时,就可以将这个特质独立出来,采用关键字trait声明。
2、scala中的trait中即可以有抽象属性和方法,也可以有具体的属性和方法,一个类可以混入(mixin)多个特征。这种感觉类似于java中的抽象类。
3、scala引入trait特征,第一可以代替java的接口,第二个也是对单继承机制的一种补充。
特质基本语法:
trait 特质名 { trait主体 }
1、采用extends关键字,如果有多个特质或存在父类,那么需要采用with关键字连接。
2、没有父类:class 类名 extends 特质1 with 特质2 with 特质3 .....
有父类:class 类名 extends 父类 with 特质1 with 特质2 with 特质3 .....
3、说明:
(1)类和特质的关系:使用继承的关系。
(2)当一个类要去继承特质时,第一个连接词是extends,后面是with。
(3)如果一个类在同事继承特质和父类时,应当把父类写在extends后。
例子:
1 object Test8_Trait { 2 def main(args: Array[String]): Unit = { 3 4 val student8: Student8 = new Student8() 5 student8.sayHei() 6 student8.study() 7 student8.dating() 8 student8.play() 9 } 10 } 11 //定义一个父类 12 class Person8 { 13 val name: String = "person" 14 var age: Int = 22 15 def sayHei(): Unit = { 16 println("hello" + name) 17 } 18 } 19 //定义一个特质 20 trait Young { 21 //声明抽象和非抽象属性 22 var age: Int 23 val name: String = "young" 24 25 //声明抽象和非抽象的方法 26 def play(): Unit = { 27 println("young people is playing") 28 } 29 def dating(): Unit 30 } 31 class Student8 extends Person8 with Young { 32 //重写冲突的属性,不然会报错 33 override val name: String = "student" 34 35 //实现抽象方法 36 def dating(): Unit = println(s"student $name is dating") 37 // 38 def study(): Unit = println(s"student $name is studing") 39 40 //重写父类方法 41 override def sayHei(): Unit = { 42 super.sayHei() 43 println(s"hei from : student " +name) 44 } 45 }

动态混入:
1 object Test9_TraitMixin { 2 def main(args: Array[String]): Unit = { 3 val student = new Student9() 4 student.study() 5 student.increase() 6 7 student.play() 8 student.increase() 9 10 student.dating() 11 student.increase() 12 println("-------------------------------") 13 14 //动态混入,可以在new的时候使用 15 val studentWithTalent = new Student9 with Talent { 16 override def dance(): Unit = println("student is good at dance") 17 override def sing(): Unit = println("student is good at sing") 18 } 19 studentWithTalent.dance() 20 21 studentWithTalent.sayHei() 22 studentWithTalent.play() 23 } 24 } 25 trait Knowledge { 26 var amount:Int = 0 27 def increase():Unit 28 } 29 30 trait Talent { 31 def sing(): Unit 32 def dance(): Unit 33 } 34 35 class Student9 extends Person8 with Young with Knowledge { 36 //重写冲突的属性,不然会报错 37 override val name: String = "student" 38 39 //实现抽象方法 40 def dating(): Unit = println(s"student $name is dating") 41 // 42 def study(): Unit = println(s"student $name is studing") 43 44 //重写父类方法 45 override def sayHei(): Unit = { 46 super.sayHei() 47 println(s"hei from : student " +name) 48 } 49 50 //实现特质中的抽象方法 51 override def increase(): Unit = { 52 amount += 1 53 println(s"student $name knowledge increased: $amount") 54 } 55 }

特征叠加:
1、如果特征中的方法重复了,调用时会使用最后一个特征(可以说是覆盖)。
2、如果确定的使用其中一个特征可以使用super[特征或者类].方法。
自身类型
1 object Test10_TraitSelfType { 2 def main(args: Array[String]): Unit = { 3 val user = new RegisterUser("wl", "123456") 4 user.insert() 5 } 6 } 7 //定义一个用户类 8 class User(val name:String, val password:String) 9 10 trait UserDao { 11 //UserDao的类型定义成了User, 可以认为UserDao里面有了一个User 12 //UserDao要使用User里的一些属性,又不想有继承的关系,相当于实现了依赖注入的功能 13 _: User => 14 //向数据库插入数据 15 def insert(): Unit = { 16 //只能使用this. 不能直接使用参数名 17 println(s"insert into db: ${this.name}") 18 } 19 } 20 21 //定义注册用户类 22 class RegisterUser(name:String, password:String) extends User(name, password) with UserDao


浙公网安备 33010602011771号