2016-04-29 1 views
1

Selon la définition de covariance:Scala - Covariance

Q [+ B] signifie que Q peut prendre une classe, mais si A est une sous-classe de B, alors Q [A] est considéré comme un sous-classe de Q [B].

Voyons voir l'exemple suivant:

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

Tout va bien, mais je ne vois pas pourquoi List1[SomeB] est une sous-classe de List1[SomeA], autrement dit pourquoi b est une sous-classe de a?

+0

Consultez le http://stackoverflow.com/questions/663254/pourquoi-dansnt-le-exemple-compile-aka-how-does-co-contra-and-in-variance-w. Je lis cette question et réponds plusieurs fois. –

Répondre

2

Maintenant, List1[SomeB] est la sous-classe de List1[SomeA] ce qui signifie que vous pouvez mettre le premier où le plus tard est nécessaire.

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

scala> val a = List1[SomeA](new SomeA{},new SomeB{}) 
a: List1[SomeA] = List1(WrappedArray([email protected], [email protected])) 

scala> val b = List1[SomeB](new SomeB{},new SomeC{}) 
b: List1[SomeB] = List1(WrappedArray([email protected], [email protected])) 

scala> val c: List1[SomeA] = b 
c: List1[SomeA] = List1(WrappedArray([email protected], [email protected])) 

scala> val c: List1[SomeA] = a 
c: List1[SomeA] = List1(WrappedArray([email protected], [email protected])) 

Si elle était invariant qui ne serait pas possible, voir:

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([email protected], [email protected])) 
1

Comme tous les éléments List1[SomeB] sont sous-type de SomeA (comme SomeB étend SomeA), vous pouvez tout simplement passer List1[SomeB]List1[SomeA] devrait.