What is variance in Scala?

Let’s start with Liskov substitution principle

Let Φ(x) be a property provable about objects x of type T. Then Φ(y) should be true for objects y of type S where S is a subtype of T.

What is Variance?

In the generic types, the variance is the correlation between the inheritance relation of the abstract types and how it is “transmitted” to the inheritance in the generic classes. Scala supports variance annotations of type parameters of generic classes, to allow them to be covariant, contravariant, or invariant.

Variance in functioning:

Invariance [T]:

A generic class invariant over its abstract type can only receive a parameter type of exactly that type.

trait Bank

trait Online extends Bank
trait Offline extends Bank

class Payment[T]

object Invariance{

  def doPayment(method:Payment[Online]){
    print(method)
  }

  doPayment(new Payment[Online]) // pass the same type
}

Covariance [+T]:

A generic class covariant over its abstract type can receive a parameter type of that type or subtypes of that type.

trait Bank

trait Online extends Bank
trait Offline extends Bank

class NetBanking extends Online
class Wallet extends Online

class Cash extends Offline
class Cheque extends Offline

class Payment[+T]

object Covariance {

  def doPayment(method:Payment[Online]){
    print(method)
  }

  doPayment(new Payment[NetBanking]) // pass subtype to supertype
}

Contravariance [-T]:

A generic class contravariant over its abstract type can receive a parameter type of that type or supertypes of that type.

trait Passenger

class Business extends Passenger

class Corprate extends Business

class AirLine[-T]

object Contravariance {

  def doPayment(method:AirLine[Corprate]){
    print(method)
  }

  doPayment(new AirLine[Business])// pass supertype to subtype
}

Comments