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