开发者学堂课程【Scala 核心编程-基础:特质构造的顺序】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/609/detail/9000
特质构造的顺序
内容介绍
一、特质构造顺序
二、整理
一、特质构造顺序
1、介绍
特质也是有构造器的,构造器中的内容由“字段的初始化”
和一些其他语句构成。具体实现请参考“特质叠加”
2、第一种特质构造顺序(声明类的同时混入特质)
混入有两种方式,一个是动态混入,一个是声明时混入。
(1)调用当前类的超类构造器
(2)第一个特质的父特质构造器
(3)第一个特质构造器
(4)第二个特 质构造器的父特质构造器,如果已经执行过,就不再执行。
(5)第二个特质构造器。
(6)重复4,5的步骤(如果有第3个,第4个特质)
(7)当前类构造器[案例演示]
trait AA
{
println("A...")
}
trait BB extends AA
{
println(B....")
}
trait CC extends BB
{
println("C....")
}
trait DD extends BB
{
println("D....")
}
class EE
{
println("E...")
}
class FF extends EE with CC with DD { 这个地方也叫混入,但是它是在声明类同时混入特质,也是类似于静态的一种方式,如果FF继承,相当于 CC DD 也被继承下来
printlnf"F...")
}
class KK extends EE
{
println("K....")
}
创建命名为 MixInSeq,选择 object。
package com. atguigu. chapter08. mixin
object MixInSeq
{
Def
main(args: Array[String]): Unit =
{
它的构建顺序跟 java 非常相似
//这时 FF 是这样形式 class FF extends EE with CC with DD
/*
调用当就类的超类构造器
第一个特质的父特质构造器,把静态声明当作一个整体对待,第一个父构造器是 CC
第一个特质构造器
第二个特质构造器的父特质构造器,如果 已经执行过,日就不再执行
第二个特质构造器
.......重复4, 5的步骤(如果有第3个,第4个特质)
当前类构造器[ 案例演示]
*/
//1. E...
//2. A...
//3. B....
//4. C....
//5. D....
//6. F....
整个走完,才执行当前类构造器。最后执行自己的构造器FF
val ff
1
= new
FF
()
FF
是在下面声明的
println(ff1)
//
val ff2 = new KK() with CC with DD
先注释
//
println(ff2)
trait AA
{
AA
是一个特质
println("A...")
}
trait BB extends AA
{
BB
继承
AA
,
第二层
,
BB
有一个父类构造器
println(B....")
}
trait CC extends BB
{
CC
继承
BB,
第三层
,
CC
有一个父类构造器
println("C....")
}
trait DD extends BB
{ DD
继承
BB,
第三层
,BB
已经构建过
println("D....")
}
class EE
{//
普通类
println("E...")
}
class FF extends EE with CC with DD
{ //先继承了EE类, 然后再继承cc和DD
printlnf"F...")
}
class KK extends EE
{ //
KK
直接继承了普通类
println("K....")
}
进行执行,执行结果如下:
D: \program\jdk8\bin\java
E...
A...
B....
C....
D....
F....
com. atguigu. chapter08. mixin. FF@4ec6a292
第一种静态的方式操作结束,第二种动态混入。
val ff
1
= new
FF
()
println(ff1)
//这时我们是动态混入
/*
先创建 new KK 对象,然后再混入其他特质
从构建的顺序可以看出,它在进行静态工作时,这个对象本身还没有创建,因此它整个流程是严格按照继承的关系进行的。
调用当前类的超类构造器
当前类构造器
第一个特质构造器的父特质构造器
第一个特质构造器
第二个特质构造器的父特质构造器,如果已经执行过,就不再执行
第二个特质构造器
......重复5, 6的步骤(如果有第3个,第4个特质)
当前类构造器[ 案例演示]
*/
//1.E...
//2.K...
//3.A...
//4.B
//5.C
//6.D
println(''
========================
=
=
" )
val ff2 = new KK() with CC with DD
静态混入是先
KK
,
再动态混入
CC with DD
println(ff2)
trait AA
{
println("A...")
}
trait BB extends AA
{
println(B....")
}
trait CC extends BB
{
println("C....")
}
trait DD extends BB
{
println("D....")
}
class EE
{//
println("E...")
}
class FF extends EE with CC with DD
{
printlnf"F...")
}
class KK extends EE
{
先把继承类部分搞定
,
然后再混入
println("
k
....")
}
执行,可以看到结果如下:
E...
K....
в....
D....
com.atguigu.chapter08. mixin . MixInSeq$$anon$1@1b40d5f0
3、第2种特质构造顺序(在构建对象时,动态混入特质)
(1)调用当前类的超类构造器
(2)当前类构造器
(3)第一个特质构造器的父特质构造器
(4)第一个特质构造器.
(5)第二个特质构造器的父特质构造器,如果已经执行过,就不再执行
(6)第二个特质构造器
(7)...重复5,6的步骤(如果有第3个,第4个特质)
(8)当前类构造器[案例演示]
4、区别:分析两种方式对构造顺序的影响
第1种方式实际是构建类对象,在混入特质时,该对象还没有创建。在混入时当作一个整体。
第2种方式实际是构造匿名子类,可以理解成在混入特质时,对象已经创建了。
二、整理
特质构造顺序
1、介绍
特质也是有构造器的,构造器中的内容由“字段的初始化”
和一些其他语句构成。具体实现请参考“特质叠加”
2、第一种特质构造顺序(声明类的同时混入特质)
混入有两种方式,一个是动态混入,一个是声明时混入。
(1)调用当前类的超类构造器
(2)第一个特质的父特质构造器
(3)第一个特质构造器
(4)第二个特 质构造器的父特质构造器,如果已经执行过,就不再执行。
(5)第二个特质构造器。
(6)重复4,5的步骤(如果有第3个,第4个特质)
(7)当前类构造器[案例演示]
3、第2种特质构造顺序(在构建对象时,动态混入特质)
(1)调用当前类的超类构造器
(2)当前类构造器
(3)第一个特质构造器的父特质构造器
(4)第一个特质构造器.
(5)第二个特质构造器的父特质构造器,如果已经执行过,就不再执行
(6)第二个特质构造器
(7)...重复5,6的步骤(如果有第3个,第4个特质)
(8)当前类构造器[案例演示]
4、区别:分析两种方式对构造顺序的影响
第1种方式实际是构建类对象,在混入特质时,该对象还没有创建。即做一个整体的创建。
第2种方式实际是构造匿名子类,可以理解成在混入特质时,对象已经创建了,会先把自己继承的做完。
5、代码演示:
package com. atguigu. chapter08. mixin
object MixInSeq
{
Def
main(args: Array[String]): Unit =
{
//这时 FF 是这样形式 class FF extends EE with CC with DD
/*
调用当就类的超类构造器
第一个特质的父特质构造器,把静态声明当作一个整体对待,第一个父构造器是 CC
第一个特质构造器
第二个特质构造器的父特质构造器,如果 已经执行过,日就不再执行
第二个特质构造器
.......重复4, 5的步骤(如果有第3个,第4个特质)
当前类构造器[ 案例演示]
*/
//1. E...
//2. A...
//3.
B....
//4. C....
//
5
.
D
....
//6
.
F
....
val ff
1
= new
FF
()
println(ff1)
//
val ff2 = new KK() with CC with DD
//
println(ff2)
trait AA
{
println("A...")
}
trait BB extends AA
{
println(B....")
}
trait CC extends BB
{
println("C....")
}
trait DD extends BB
{
println("D....")
}
class EE
{//
普通类
println("E...")
}
class FF extends EE with CC with DD
{ //先继承了EE类, 然后再继承cc和DD
printlnf"F...")
}
class KK extends EE
{ //
KK
直接继承了普通类
println("K....")
}
val ff
1
= new
FF
()
println(ff1)
//这时我们是动态混入
/*
调用当前类的超类构造器
当前类构造器
第一个特质构造器的父特质构造器
第一个特质构造器
第二个特质构造器的父特质构造器,如果已经执行过,就不再执行
第二个特质构造器
......重复5, 6的步骤(如果有第3个,第4个特质)
当前类构造器[ 案例演示]
*/
//1.E...
//2.K...
//3.A...
//4.B
//5.C
//6.D
println(''
========================
=
=
" )
val ff2 = new KK() with CC with DD
println(ff2)
trait AA
{
println("A...")
}
trait BB extends AA
{
println(B....")
}
trait CC extends BB
{
println("C....")
}
trait DD extends BB
{
println("D....")
}
class EE
{//
println("E...")
}
class FF extends EE with CC with DD
{
printlnf"F...")
}
class KK extends EE
{
println("
k
....")
}