Coursera Scala 4-3:子类型和泛型
Coursera Scala 4-3:子类型和泛型
Type Bounds
def assertAllPos[S <: IntSet](r: S): S = ...
- S <: T 表示S是T的子类
- S >: T表示S是T的父类
也可以这么用:
[S >: NonEmpty <: IntSet]
协变covariant
这个的意思是:
如果List是convariant的,S<:T (S是T的子类)成立,那么List[S]<:List[T]也成立
covariant带来的问题:
NonEmpty[] a=new NonEmpty[]{new NonEmpty(1,Empty,Empty)}
IntSet[] b = a
b[0]=Empty
NonEmpty s=a[0]
Empty不是NonEmpty 若执行肯定会错
这里NonEmpty是Inset的子类 java中Array是covariant的
所以 第二行成立 但Empty不是NonEmpty
java中的解决方法是在创建Array的时候就放入一个表明最初创建类型的Tag
因为Empty不是NonEmpty类型的 所以 b[0]=Empty这句话就会报错(所以是个运行时的错误)
scala中的Array就不是corvariant的:
var x=ArrayAny
var y=ArrayInt
x=y //这里报错 type mismatch; found : Array[Int] required: Array[Any]
里氏替换原则:
Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.
if S<:T then q(x:T)==true ==> q(y:S)==true
如果下A<:B 那么对B能进行的操作 对A也可以进行
或者说对于q(x) x是B类型的能工作 那么q(y) y是A类型的也能工作如果A<:B
也就是 父类型能做的 子类型也要能做
要达到这个 父类方法的参数类型要比子类的"窄"(父类的参数类型要是子类参数类型的子类) 但父类方法的返回值类型应该要比子类的"宽"
逆变
Reference
最后更新:2017-04-03 05:39:17