scala之trait理解

xiaoxiao2021-02-28  122

核心内容:  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") } } 123456789101112131415161718192021222324252627282930313233 123456789101112131415161718192021222324252627282930313233

程序的运行结果:

Human teacher! PianoPlayer! teacher and pianoplayer I am PianoPlayer and Teacher I am a PianoPlayer! 123456 123456

对于上面这个程序,用我们上面构造器的执行顺序来分析的话,构造器的执行顺序为:    实例程序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!")} } 123456789101112131415161718192021222324252627 123456789101112131415161718192021222324252627

运行结果:

Human teacher! PianoPlayer! I am a PianoPlayer! I am a teacher! 12345 12345

构造器的执行顺序: 

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......") } 12345678910111213141516171819202122232425 12345678910111213141516171819202122232425

运行结果:

Hello Scala! Working...... Hello Spark! 123 123

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

转载请注明原文地址: https://www.6miu.com/read-29997.html

最新回复(0)