scala之trait理解

来源:互联网 发布:emacs26 for windows 编辑:程序博客网 时间:2024/06/14 03:26

核心内容: 
1、混入特质trait的3种方式 
2、多重继承构造器执行顺序 
3、基于trait的AOP代码实战


1、混入特质的3种方式以及多重继承构造器的执行顺序

1、除了在类定义中混入特质以外,还可以在特质定义中混入特质以及在对象构造时混入特质 
(注意:创建对象时混入特质,要重写trait中的抽象方法 ) 
2、特质的构造是有顺序的,从左到右依次构造,并且父类构造器不重复构造 
构造器按如下顺序构造: 
(1)超类 
(2)父特质 
(3)第一个特质 
(4)第二个特质(父特质不重复构造) 
(5)类 
如果class A extends B1 with B2 with B3…. 
那么,串接B1、B2、B3…等特质,去掉重复项且右侧胜出


实例程序1:在类定义中混入特质并分析构造器的执行顺序

object App6 {   def main(args:Array[String]):Unit=   {       val  aa = new PianoTeacher       aa.teach()       aa.play   }}//混入特质的第一种方式class Human{   println("Human")  }trait Teacher extends Human   {   println("teacher!")   def teach()  //特质中定义一个抽象方法}trait PianoPlayer extends Human{   println("PianoPlayer!")   def play={println("I am a PianoPlayer!")}}//定义一个子类并在类的定义当中混入特质class PianoTeacher extends  Human with Teacher with PianoPlayer {   println("teacher and pianoplayer")   override def teach()=  //实现了Teacher接口中teach方法   {     println("I am PianoPlayer and Teacher")   }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

程序的运行结果:

Humanteacher!PianoPlayer!teacher and pianoplayerI am PianoPlayer and TeacherI am a PianoPlayer!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

对于上面这个程序,用我们上面构造器的执行顺序来分析的话,构造器的执行顺序为: 
这里写图片描述 
实例程序2:在构造对象时混入特质并分析构造器的执行顺序

object App6 {   def main(args:Array[String]):Unit=   {       val aa = new Human() with Teacher with PianoPlayer       {         def teach()={println("I am a teacher!")}       }//在定义对象时混入特质并实现特质中的未实现的方法       aa.play       aa.teach()   }}//混入特质的第一种方式class Human                       {   println("Human")  }trait Teacher extends Human   {   println("teacher!")   def teach()  //特质中定义一个抽象方法}trait PianoPlayer extends Human{   println("PianoPlayer!")   def play={println("I am a PianoPlayer!")}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

运行结果:

Humanteacher!PianoPlayer!I am a PianoPlayer!I am a teacher!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

构造器的执行顺序: 
这里写图片描述

2、基于trait的AOP代码实战

1、特质的另一个应用方面在于:为类提供可堆叠的改变(super保留字) 
 当为类添加多个互相调用的特质时,从最后一个开始进行处理 
 在类中super.foo()这样的方法调用是静态绑定的,明确是调用它的父类的foo()方法 
 在特质中写下了super.foo()时,它的调用是动态绑定的。调用的实现将在每一次特质被混入到具体类的时候才被决定 
 因此,特质混入的次序的不同其执行效果也就不同


实例程序:

object App6 {   def main(args:Array[String]):Unit=   {      val aa = new Work with TBeforeAfter      aa.doAction   }}trait Action{  def doAction  }trait TBeforeAfter extends Action{  abstract  override def doAction  {     println("Hello Scala!")     super.doAction      println("Hello Spark!")  }}class Work extends Action{  override def doAction = println("Working......")  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

运行结果:

Hello Scala!Working......Hello Spark!
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

如有问题,欢迎留言指正! 
参考网址: 
1、http://blog.csdn.net/hwssg/article/details/37810095 
2、http://blog.csdn.net/expt/article/details/782609

原创粉丝点击