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

2015/11/20 07:46

B是A的子类，A是B的父类。

##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
``````

cov不能赋值给cov2，因为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)}
}
``````

``````    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)
}
``````

``````    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]。 它声明了一个类型A,隐式地有一个类型B[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的协变和逆变上界与下界

6
56 收藏

### 作者的其它热门文章

2015/11/22 12:38

2015/11/21 10:18

#### 引用来自“pseudo”的评论

2015/11/21 10:17

scala里居然还有这种概念啊……学过相对论或者微分几何的应该知道逆变张量和协变张量是什么
2015/11/21 09:19

2015/11/21 08:18

5 评论
56 收藏
6