特质构造的顺序|学习笔记

简介: 快速学习特质构造的顺序。

开发者学堂课程【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 ff1 = 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 ff1 = 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 ff1 = 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 ff1 = 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....")

}

相关文章
|
3天前
|
存储 索引 Python
什么是数组,什么是对象,并说出他们的区别
什么是数组,什么是对象,并说出他们的区别
15 6
|
3天前
|
Java 程序员
揭秘编程世界的构造块:一文教你理解方法的本质与运用
揭秘编程世界的构造块:一文教你理解方法的本质与运用
8 0
|
3天前
|
算法 编译器 C++
【C++ 模板编程 基础知识】C++ 模板类部分特例化的参数顺序
【C++ 模板编程 基础知识】C++ 模板类部分特例化的参数顺序
25 0
|
3天前
|
存储 Java 程序员
Java数组全套深入探究——基础知识阶段2、数组的定义语法
Java数组全套深入探究——基础知识阶段2、数组的定义语法
32 0
|
3天前
|
算法 Java 程序员
Java数组全套深入探究——基础知识阶段4、数组的遍历
Java数组全套深入探究——基础知识阶段4、数组的遍历
39 0
|
3天前
|
存储 Java 程序员
Java数组全套深入探究——基础知识阶段3、数组下标操作
Java数组全套深入探究——基础知识阶段3、数组下标操作
31 0
|
9月前
|
存储 算法 编译器
【C++技能树】令常规运算符用在类上 --类的六个成员函数II
C++中为了增强代码的可读性,加入了运算符的重载,与其他函数重载一样
38 0
|
11月前
|
C++
【C++系列P5】‘类与对象‘-三部曲——[对象&特殊成员](3/3)
【C++系列P5】‘类与对象‘-三部曲——[对象&特殊成员](3/3)
|
12月前
|
存储 编译器 C++
【C++】list迭代器的深度剖析及模拟实现(感受类封装,类和对象的思想)
【C++】list迭代器的深度剖析及模拟实现(感受类封装,类和对象的思想)
通过代码加解析的方式带领大家分析 :数组与指针的关系
通过代码加解析的方式带领大家分析 :数组与指针的关系
63 0
通过代码加解析的方式带领大家分析 :数组与指针的关系