有时我们需要标注一个对象的类型是其他多个对象的子类型。在Scala中我可以用复合类型去标记多个类型的交集。
如下我们有两个特性Cloneable和Resetable:
trait Cloneable extends java.lang.Cloneable { override def clone(): Cloneable = { super.clone().asInstanceOf[Cloneable] } } trait Resetable { def reset: Unit }
现在我想要实现一个cloneAndReset函数,用来传递一个对象,复制这个对象然后重置原来的对象。
def cloneAndReset(obj: ?): Cloneable = { val cloned = obj.clone() obj.reset cloned }
问题是这个参数对象,如果它是Cloneable类型,这个对象可以clone但是不能reset;如果它是Resetable类型,我们可以reset但是它不能clone操作。为了避免这种情况,我们需要指明obj的类型必须同时是Cloneable和Resetable。复合类型在Scala中的写法如下:Cloneable with Resetable.
下面是修改过的函数:
def cloneAndReset(obj: Cloneable with Resetable): Cloneable = { //... }
复合类型可以由多个对象类型构成,并且它们具有一个单一的改进方式,用来缩小这个对象成员签名范围。一般的格式为:A with B with C ... { refinement }
改进方式可以查看混合组成类中的例子。