It means define trait Option[T] is same as trait Option[+T].
It's easy to consider val humanOpt: Option[Human] can point to a Option[Student] instance just like val humanOpt: Human can point to a Student instance.
Maybe it seems some strange but why I consider this?
Java variable default as polymorphism which compare with c++ that it should use virtual keyword.I think its a important point to simplify OO in Java.
Scala use high order type in many use case that is more frequently compare to Java, such as Option, Try or define a Cache[T] by ourselves.
Besides, it still comply with Liskov Substitution principle.
I just want to know why not simplify covariant as default behavior?
If your
Cachehas aput(T)method, it can't be covariant, exactly because of the Liskov substitution principle.So making all types covariant by default simply won't work.
You could use variance inference instead: if type can be covariant make it covariant, if it can be contravariant make if contravariant, if neither make it invariant. But then just adding a method can change the variance and break a lot of code using your type. By making all variance explicit you are forced to notice when you do that.