Type Bounds
OOP裡面有subclassing的關係,一個superclass pointer可以指向其subclass instance,因為所有能在supertype執行的動作與屬性,都能在其subclass做到。subclassing是polymorphism的一種。
Scala提供另一種polymorphism: generics。
假設有一個function定義如下:
IntSet假設有兩個subclass: NonEmpty 以及 Empty。
所以這個assertAllPos有可能接受任一種subclass instance,也有可能回傳任一種subclass instance。
不過其實際上執行的邏輯是:如果input是NonEmpty,則output一定是NonEmpty,對Empty來說也是一樣。
所以Scala可以利用generics和“type bounds”來達成這種更正確的宣告。
“A <: B”意思是A是B的subclass
用簡單例子來看,假設有以下class hierarchy:
class A {} class B extends A {} class C extends A {} class D extends B {}
def f(x: A): A = { x }
def f2[T <: A](x: T): T = x //我們接受和回傳的type T只能是A的subtype(包括A)
如果執行以下statement,則可以看出return type都是A:
f(new A) f(new B) f(new C) f(new D)
res0: A = A@63f64c3c
res1: A = B@48034736
res2: A = C@4d2b401b
res3: A = D@7fdb9e4e
但是如果執行f2,可以看出input type就是return type,因為我們使用了 type parameter [T <: A]
f2(new A) f2(new B) f2(new C) f2(new D)
res4: A = A@192224
res5: B = B@152f208
res6: C = C@148d260e
res7: D = D@4c13ac62
我們也可以同時設定upper and lower type bound,這樣限定可以input的type:
def f3[T >:D <: B](x: T) : T = x
//f3(new A) //不符合type boundsf3(new B) //f3(new C) //不符合type bounds f3(new D)
沒有留言:
張貼留言