As per the definition of contravariance (super class instances will be accepted), my last statement in the below code snippet, should be accepted; but it is thrown with type error. Can you please correct my understanding.
class A
class B extends A
class C extends B
abstract class Box[-T] {
def set(x : T) :Unit
}
val x = new Box[B] {
def set(b:B) = Console println "B"
}
val y = new Box[A] {
def set(a:A) = Console println "A"
}
val z = new Box[C] {
def set(c:C) = Console println "C"
}
x.set(new A) <-- Type error
But x.set(new C)
is fine, So even though "contravariant parameters are accepted as method parameters" is in fact. are covariant parameters actually.
You are confusing how contravariance works. x
is a Box[B] as such, set
accepts values of type B
(or any subtype of B
because that is what Liskvo says) .
However, Box[A] is a subtype of a Box[B] . So you could have passed y
where x
is expected. Because a Box that can store any A
can store a B
.
But, a Box that can store only B
s can not store and arbitrary A
.
It looks like this not how it would work and that's from a conceptual stand point: a B
is an A
but not the other way around.
As indicated in thescala doc for variances , contravariant type parameters allow to pass a "super-type" instead of the "sub-type", but this applies to what is used within the body (eg If the "super-type" already has defined what's used) otherwise I guess it just considers the type and we're back to what I explained before.
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.