# scala-协变、逆变、上界、下界

## Scala的协变

    class Animal {}
class Bird extends Animal {}
class Animal {}
class Bird extends Animal {}
//协变
class Covariant[T](t:T){}
val cov = new Covariant[Bird](new Bird)
val cov2:Covariant[Animal] = cov


c不能赋值给c2，因为Covariant定义成不变类型。

    class Animal {}
class Bird extends Animal {}
class Animal {}
class Bird extends Animal {}
//协变
class Covariant[+T](t:T){}
val cov = new Covariant[Bird](new Bird)
val cov2:Covariant[Animal] = cov


## Scala的逆变

    class Animal {}
class Bird extends Animal {}
class Contravariant[-T](t: T) {
}
val c: Contravariant[Animal] = new Contravariant[Animal](new Animal)
val c2: Contravariant[Bird] = c


## 下界lower bounds

    class Animal {}
class Bird extends Animal {}
class Consumer[+T](t: T) {
def use(t: T) = {}
}


    class Animal {}
class Bird extends Animal {}
class Consumer[+T](t: T) {
def get(): T = {new T}
}


    class Animal {}
class Bird extends Animal {}
class Consumer[+T](t: T) {
def use[U >: T](u : U) = {println(u)}
}


## 上界upper bounds

    class Animal {}
class Bird extends Animal {}
class Consumer[-T](t: T) {
def get[U <: T](): U = {new U}
}


    class Animal {}
class Bird extends Animal {}
class Consumer[-S,+T]() {
def m1[U >: T](u: U): T = {new T} //协变，下界
def m2[U <: S](s: S): U = {new U} //逆变，上界
}
class Test extends App {
val c:Consumer[Animal,Bird] = new Consumer[Animal,Bird]()
val c2:Consumer[Bird,Animal] = c
c2.m1(new Animal)
c2.m2(new Bird)
}


## View Bound <%

Scala还有一种视图绑定的功能，如

    class Bird {def sing = {}}
class Toy {}
class Consumer[T <% Bird]() {
def use(t: T) = t.sing
}


    class Bird {def sing = {}}
class Toy {}
class Consumer() {
def use[T <% Bird](t: T) = t.sing
}
class Test extends App {
val c = new Consumer()
c.use(new Toy)
}


No implicit view available from Toy => Bird.

    import scala.language.implicitConversions
class Bird {def sing = {}}
class Toy {}
class Consumer() {
def use[T <% Bird](t: T) = t.sing
}
class Test extends App {
implicit def toy2Bird(t: Toy) = new Bird
val c = new Consumer()
c.use(new Toy)
}


## Context Bound

context bound在Scala 2.8.0中引入，也被称作type class pattern。
view bound使用A <% String方式，context bound则需要参数化的类型，如Ordered[A]。

    def f[A : B](a: A) = g(a) // where g requires an implicit value of type B[A]


    def f[A : ClassManifest](n: Int) = new Array[A](n)


    def f[A : Ordering](a: A, b: A) = implicitly[Ordering[A]].compare(a, b)


## 参考

Scala中的协变，逆变，上界，下界等

Scala的协变和逆变上界与下界

posted @ 2015-11-20 07:58  TheBug  阅读(...)  评论(...编辑  收藏