特质

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

 

posted @ 2022-05-15 15:14  小王同学学编程  阅读(184)  评论(0)    收藏  举报
levels of contents