通俗地解释scala中叠加特质的构建顺序和执行顺序
- 闲话不说,先上一段代码。
1 object MixInDemo02 {
2 def main(args: Array[String]): Unit = {
3 val mysql4 = new MySQL4 with File4 with DB4
4 mysql4.insert(100)
5
6 // 执行结果如下
7 // Operate4...
8 // Data4
9 // File4
10 // DB4
11 // 向数据库
12 // 向文件
13 // 插入数据 = 100
14 }
15 }
16
17 trait Operate4 {
18 println("Operate4...")
19 def insert(id : Int)
20 }
21
22 trait Data4 extends Operate4 {
23 println("Data4")
24 override def insert(id : Int): Unit = {
25 println("插入数据 = " + id)
26 }
27 }
28
29 trait DB4 extends Data4 {
30 println("DB4")
31 override def insert(id : Int): Unit = {
32 println("向数据库")
33 super.insert(id)
34 }
35 }
36
37 trait File4 extends Data4 {
38 println("File4")
39 override def insert(id : Int): Unit = {
40 println("向文件")
41 super.insert(id)
42 }}
43 class MySQL4 {}
- 解释第3行代码(val mysql4 = new MySQL4 with File4 with DB4),构造mysql4对象的过程。
多特质叠加的时候,构造对象是从左往右开始。
- 首先执行File4的构造器,一看继承了Data4,所以去找Data4的构造器,再看到Data4又继承了Operate4,所以又去找Operate4的构造器。由于Operate4上面没有超类了,所以就开始执行构造器的代码,println("Operate4...")。然后执行Data4的构造器代码,println("Data4")。最后才执行File4的构造器代码, println("File4")。
- 然后执行DB4的构造器,DB4也继承了Data4,但是上一步Data4的构造器代码已经被执行过一遍了,所以这时就不会再执行了。直接执行DB4的构造器代码, println("DB4")。
- 通过以上两步,mysql4对象就构造完毕,输出语句的顺序为:Operate4... -> Data4 -> File4 -> DB4。
- 解释第4行代码(mysql4.insert(100))的执行顺序
多特质叠加的时候,执行叠加对象里的的方法是从右往左开始。
- 首先执行DB4中的insert方法,即执行代码println("向数据库"),然后执行代码super.insert(id)。
- 这个时候需要注意的是,这里的super不再指的是Data4了,而是第3行代码(new MySQL4 with File4 with DB4)中的File4对象,因此开始执行File4中的insert方法,即println("向文件"),然后执行super.insert(id)。
- 由于File4左边已经没有其他特质了,所以这里的super就指的是Data4,即执行Data4中的insert方法,println("插入数据 = " + id)。
- 通过以上三步,insert方法就执行完毕,输出语句的顺序为:向数据库 -> 向文件 -> 插入数据 = 100。