类型上界限制了一个类型是另外一个类型的子类型,而类型下界则声明了一个类型是另外一个类型的父类型。B >: A表明了类型参数B或者抽象类型B是类型A的超类。在大多数场景中,A是作为类的类型参数,而B会作为方法的类型参数。
1 | trait Node[+B] { |
这个程序实现了一个单向链表。Nil表示一个空的元素(比如一个空的列表)。class ListNode是一个Node,它包含了一个类型B的元素(head)和一个列表中其余元素的引用(tail)。class Node和它的子类型是协变的,因为这里有+B。
然而,这个程序不能通过编译,因为prepend方法中的参数elem是B类型的,且声明了为协变的。这之所以行不通,是在于函数在它们的参数类型上是逆变的,而在它们的返回类型上是协变的。
为了解决这个问题,我们需要转变prepend方法中参数类型的型变。我们可以引用新的类型U,它的类型下界是B,从而实现这一转变。
1 | trait Node[+B] { |
现在我们便可以像下面这样操作了:
1 | trait Bird |
Node[Bird]被分配到africanSwallowList,但是仍然可以接受EuropeanSwallow。