Классическим примером являются функции, использующие интерфейс Scala для функции с одним аргументом:
trait Function1[-T1, +R]
, который является контравариантным (-
) для аргумента и ковариантным (+
)) для возвращаемого типа.
Почему?
Представьте, что у вас есть эти классы:
class Timelord { ... }
class Doctor extends Timelord { ... }
class Enemy { ... }
class Dalek extends Enemy { ... }
Если у вас есть метод, который в качестве параметра принимает Doctor => Enemy
функция;тогда все в порядке, чтобы предоставить экземпляр TimeLord => Enemy
.Он по-прежнему будет принимать экземпляры Doctor
.
Так что TimeLord => Enemy
является подклассом из Doctor => Enemy
, поскольку TimeLord
является суперклассом из Doctor
, это контравариантный в этом параметре.
Аналогично, функция, возвращающая Dalek
, действительна, когда вам нужна функция, возвращающая некоторое Enemy
, потому что Dalek
is-anEnemy
Итак, Doctor => Dalek
является подклассом из Doctor => Enemy
, потому что Dalek
является подклассом из Enemy
, это ковариантный в этом параметре.