Scala学习笔记(八) - 特质

来源:互联网 发布:jquery清空表单数据 编辑:程序博客网 时间:2024/04/24 08:12

特质 trait 是Scala中特有的一项特点,不同于C#与Java,如果一定要拿C#与Java中的某项特点作对比的话,最接近的应该是接口,但是C#与Java中的接口是不允许带有方法实现的,而Scala中的Trait是可以带有方法实现的。

定义特质:

预定义类是一样的只是关键字变了

trait XX{

def method (){ ...}

}

使用特质:

class F extends XX { }

这样既可以在F中直接使用特质XX的method了,因为特质中的method已经实现了,则不需要再重复实现。

*胖接口与瘦接口

相对于C#和Java的接口来说,Scala中的接口都相对较胖,因为Scala中可以带着实现方法,而C#与Java中则不可以,所以C#与Java的接口相对来说要瘦很多,而且相信大家都有过这种体验,就是经常同样的一个接口的不同实现,需要写很多重复的方法签名,所以Scala中的特质可以改变这个现象。

特质的堆叠:

因为特质是可以继承多个的,所以特质产生的效果也是可以堆叠的,例如:

// 定义一个抽象类,有一个方法get

abstract class IntSample{

def get(x : Int)

}
// 定义一个类继承自IntSample,get方法直接返回X
class BaseIntSample extends IntSample{

def get(x : Int){ x }

}

// 定义一个特质A,将返回的值 * 2

trait A extents IntSample{

      abstract override def get(x: Int) { super.get( 2 * x ) }

}
// 定义一个特质B,将返回的值 +1

trait B extents IntSample{

      abstract override def get(x: Int) { super.get( x + 1) }

}

// 定义一个实现类

val int = (new BaseIntSample with A with B)

int.get(1)

则,得到结果:4

理由是,执行时,先执行A的get,碰到了super则继续调用B的get,B的get返回了 2,则A继续执行,则返回4

如果将代码稍微修改下:

val int = (new BaseIntSample with B with A)

int.get(1)

则,返回值是 3。

特质相对于多重继承来说的好处是,他的结果是可以堆积的,而多重继承不可以。

特质的执行顺序,特质的执行顺序简单的说,就是从外向内一层层执行,如果两个特质继承自同一个类的时候,则先暂停该类的执行,再去执行另外的特质,直到这个类的所有子特质都执行完成:


其中的黑线是执行是顺序,白色箭头是继承关系。

因为Scala中的特质是动态混入的,所以运行时会消耗一些微乎其微的性能,但是因为执行顺序的问题,也可能会造成混乱,所以,具体的使用还需要多多考虑才行。

0 0
原创粉丝点击