- "preparagraph": "Scala's type system has to account for class hierarchies together with polymorphism. Class hierarchies allow the expression of subtype relationships. A central question that comes up when mixing OO with polymorphism is: if `T'` is a subclass of `T`, is `Container[T']` considered a subclass of `Container[T]`? Variance annotations allow you to express the following relationships between class hierarchies & polymorphic types:\n\n####Covariant:\n- `C[T']` is a subclass of `C[T]`\n- Scala notation: `[+T]`\n\n####Contravariant:\n- `C[T]` is a subclass of `C[T']`\n- Scala notation: `[-T]` \n\n####Invariant:\n- `C[T]` and `C[T']` are not related\n- Scala notation: `[T]` \n\n\nThat one probably blew your mind. Now if you assign a type to the instantiation, that's different to the variable type, you'll have problems. You may want to take time after this o compare this koan with the previous koan to compare and contrast. \n\n```\nclass MyContainer[A](a: A)(implicit manifest: scala.reflect.Manifest[A]) {\n private[this] var item = a\n\n def get = item\n\n def set(a: A) {\n item = a\n }\n\n def contents = manifest.runtimeClass.getSimpleName\n}\n\n// Uncomment the following line\n// val fruitBasket:MyContainer[Fruit] = new MyContainer[Orange](new Orange())\n```\n\nSo, if you want to set a Fruit basket to an orange basket so how do we fix that? You make it covariant using `+`. This will allow you to set the your container to a either a variable with the same type or parent type. In other words, you can assign `MyContainer[Fruit]` or `MyContainer[Citrus]`.",
0 commit comments