scala之trait理解

核心内容: 
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

程序的运行结果:

Human
teacher!
PianoPlayer!
teacher and pianoplayer
I am PianoPlayer and Teacher
I 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

运行结果:

Human
teacher!
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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值