简体   繁体   中英

Scala - Covariance

According to covariance definition:

Q[+B] means that Q can take any class, but if A is a subclass of B, then Q[A] is considered to be a subclass of Q[B].

Let's see the following example:

trait SomeA
trait SomeB extends SomeA
trait SomeC extends SomeB

case class List1[+B](elements: B*) 

val a = List1[SomeA](new SomeA{},new SomeB{})
val b = List1[SomeB](new SomeB{},new SomeC{})

Everything is fine, but I don't see why List1[SomeB] is a subclass of List1[SomeA] , or in other words why b is a subclass of a ?

Now, List1[SomeB] is subclass of List1[SomeA] which means you can put the first where the later is needed.

scala> case class List1[+B](elements: B*)

scala> val a = List1[SomeA](new SomeA{},new SomeB{})
a: List1[SomeA] = List1(WrappedArray($anon$2@3e48e859, $anon$1@31ddd4a4))

scala> val b = List1[SomeB](new SomeB{},new SomeC{})
b: List1[SomeB] = List1(WrappedArray($anon$2@5e8c34a0, $anon$1@7c1c5936))

scala> val c: List1[SomeA] = b
c: List1[SomeA] = List1(WrappedArray($anon$2@5e8c34a0, $anon$1@7c1c5936))

scala> val c: List1[SomeA] = a
c: List1[SomeA] = List1(WrappedArray($anon$2@3e48e859, $anon$1@31ddd4a4))

If it were invariant that would be not possible, see:

scala> case class List1[B](elements: B*)
defined class List1

scala> val c: List1[SomeA] = b
<console>:16: error: type mismatch;
 found   : List1[SomeB]
 required: List1[SomeA]
Note: SomeB <: SomeA, but class List1 is invariant in type B.
You may wish to define B as +B instead. (SLS 4.5)
       val c: List1[SomeA] = b
                             ^

scala> val c: List1[SomeA] = a
c: List1[SomeA] = List1(WrappedArray($anon$2@45acdd11, $anon$1@3f0d6038))

由于所有元件List1[SomeB]是亚型SomeA (如SomeB延伸SomeA ),就可以简单地传递List1[SomeB]其中List1[SomeA]预计。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM