scala协变与逆变

协变

假设有类G(或者接口和特征)和类型T1、T2,在T1是T2的子类的情况下如果G< T1>也是G< T2>的子类,那么类G就是协变的。例如:

trait Link[+T]

父类协变,子类也得协变

scala> trait A[+T]
scala> class C[T] extends A[T]  // Cinvariant
scala> class X; class Y extends X;
scala> val t:C[X] = new C[Y]
<console>:11: error: type mismatch; 
 found   : C[Y]
 required: C[X]
Note: Y <: X, but class C is invariant in type T.
You may wish to define T as +T instead. (SLS 4.5)

scala> class C[+T] extends A[T]
scala> val t:C[X] = new C[Y]
t: C[X] = C@6a079142

例子:

//在方法prepend中发上了协变,所以Link必须是协变的
class Link[+T](val head: T, val tail: Link[T]) {
    //错误的方法:看上去应该没有问题,但是编译错误
    //def prepend(newHead: T): Link[T] = new Link(newHead, this)
    //正确的方法:在发生协变的方法上必须使用范型限定
    def prepend[U >: T](newHead: U): Link[U] = new Link(newHead, this)
}

逆变

假设有类G(或者接口和特征)和类型T1、T2。在T1是T2的子类的情况下如果G< T2>也是G< T1>的子类(与协变是相反的),那么类G就是逆变的。例如:

trait Link[-T]

总结

参数是逆变的或者不变的,返回值是协变的或者不变的。

。。。更新中。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值