Scala | Variances

10 Apr, 2019
Variance is the interconnection of Sub-Typing relationships which are either of complicated types or of their constituent types. Variance explains inheritance correlation of Types that have parameters or arguments within them. These types belongs to the generic classes, which takes a type like a parameter. In the presence of Variance one can create relations between complicated types and in its absence we won’t be able to reiterate the abstraction class. The Scala Variances are of three types, which are as follows:
CovariantContravariantInvariant
Covariant
Contravariant
Invariant
Some important points:
In Scala collection’s types can be constructed more securely through Variances.
Variances can provide us with some extra adjustable advancements.
It also helps in the development of authentic applications.
Variances can be applied on any Scala Types like List, Sets, etc.
Let’s discuss each type in detail.
Covariant: If a generic class has a type parameter T, then its Covariant notation will be [+T]. Suppose, we have two List types of Scala i.e, S and T. where, S is sub-type of T, then you can say that List[S] is also the sub-type of List[T]. If two types are related like this then they fall under the Covariant type. List[T] can be called as Generic.Syntax:List[+T]Here, T is the type parameter and + is the symbol of Covariance.Example:// Scala program of covariant// type  // Creating an abstract class// for Studentabstract class Student{    def name: String}  // Creating a sub-class Girls// of Studentcase class Girls(name: String) extends Student  // Creating a sub-class Boys// of Studentcase class Boys(name: String) extends Student  // Creating an Object Covariance// that inherits main method of// Appobject Covariance extends App{    // Creating a method    def Studentnames(students: List[Student]): Unit =    {        students.foreach { student =>              // Displays students name        println(student.name)    }    }      // Assigning names     val boys: List[Boys] = List(Boys("Kanchan"), Boys("Rahul"))    val girls: List[Girls] = List(Girls("Nidhi"), Girls("Geeta"))      // Accessing list of boys    Studentnames(boys)      // Accessing list of girls    Studentnames(girls)}Output:Kanchan
Rahul
Nidhi
Geeta
Here, List of boys and girls both belongs to the List of students as they are its sub-type and so, here names of all the students are displayed when the Super-type Student is called.Note:Abstract class is utilized here to apply covariance as it has List[+T] with it where, the type parameter T is covariant.A trait App is used here to speedily change objects into workable programs.
List[+T]
Here, T is the type parameter and + is the symbol of Covariance.Example:
// Scala program of covariant// type  // Creating an abstract class// for Studentabstract class Student{    def name: String}  // Creating a sub-class Girls// of Studentcase class Girls(name: String) extends Student  // Creating a sub-class Boys// of Studentcase class Boys(name: String) extends Student  // Creating an Object Covariance// that inherits main method of// Appobject Covariance extends App{    // Creating a method    def Studentnames(students: List[Student]): Unit =    {        students.foreach { student =>              // Displays students name        println(student.name)    }    }      // Assigning names     val boys: List[Boys] = List(Boys("Kanchan"), Boys("Rahul"))    val girls: List[Girls] = List(Girls("Nidhi"), Girls("Geeta"))      // Accessing list of boys    Studentnames(boys)      // Accessing list of girls    Studentnames(girls)}
Kanchan
Rahul
Nidhi
Geeta

Here, List of boys and girls both belongs to the List of students as they are its sub-type and so, here names of all the students are displayed when the Super-type Student is called.Note:
Abstract class is utilized here to apply covariance as it has List[+T] with it where, the type parameter T is covariant.
A trait App is used here to speedily change objects into workable programs.
 
Contravariant: If a generic class has a type parameter T, then its Contravariant notation will be [-T]. Suppose, we have two List types of Scala i.e, S and T. where, S is sub-type of T, but List[T] is the sub-type of List[S]. If two types are related like this then they fall under the Contravariant type. It is opposite of covariant.Syntax:List[-T]Here, T is the type parameter and – is the symbol of Contravariance.Example:// Scala program of Variance of// Contravariant type  // abstract class with a contravariant // type parameterabstract class Show[-T] {      // Method for printing    // type T    def print(value: T): Unit}  // A class structureabstract class Vehicle{    def name: String}  // Creating sub-class of Vehiclecase class Car(name: String) extends Vehicle  // Creating sub-class of class// Showclass VehicleShow extends Show[Vehicle] {    def print(vehicle: Vehicle): Unit =      // Displays name of the vehicle    println("The name of the vehicle is: " + vehicle.name)}  // Creating sub-class of class// Showclass CarShow extends Show[Car] {    def print(car: Car): Unit =      // Displays name of the car    println("The name of the car is: " + car.name)}  // Inheriting main method of // the trait Appobject Contravariance extends App {      // Assigning value to the name     val newCar: Car = Car("Scorpio")      // Defining a method that    // prints the name    def printnewCar(show: Show[Car]): Unit =     {        show.print(newCar)    }      // Creating objects    val showcar: Show[Car] = new CarShow    val showvehicle: Show[Vehicle] = new VehicleShow      // Accessing name    printnewCar(showcar)    printnewCar(showvehicle)}Output:The name of the car is: Scorpio
The name of the vehicle is: Scorpio
It is Contravariant so, we are able to substitute Show[Vehicle] for Show[Car] and that’s why both vehicle and car returns the same name.
List[-T]
Here, T is the type parameter and – is the symbol of Contravariance.Example:
// Scala program of Variance of// Contravariant type  // abstract class with a contravariant // type parameterabstract class Show[-T] {      // Method for printing    // type T    def print(value: T): Unit}  // A class structureabstract class Vehicle{    def name: String}  // Creating sub-class of Vehiclecase class Car(name: String) extends Vehicle  // Creating sub-class of class// Showclass VehicleShow extends Show[Vehicle] {    def print(vehicle: Vehicle): Unit =      // Displays name of the vehicle    println("The name of the vehicle is: " + vehicle.name)}  // Creating sub-class of class// Showclass CarShow extends Show[Car] {    def print(car: Car): Unit =      // Displays name of the car    println("The name of the car is: " + car.name)}  // Inheriting main method of // the trait Appobject Contravariance extends App {      // Assigning value to the name     val newCar: Car = Car("Scorpio")      // Defining a method that    // prints the name    def printnewCar(show: Show[Car]): Unit =     {        show.print(newCar)    }      // Creating objects    val showcar: Show[Car] = new CarShow    val showvehicle: Show[Vehicle] = new VehicleShow      // Accessing name    printnewCar(showcar)    printnewCar(showvehicle)}
The name of the car is: Scorpio
The name of the vehicle is: Scorpio

It is Contravariant so, we are able to substitute Show[Vehicle] for Show[Car] and that’s why both vehicle and car returns the same name.
Invariant: In Scala, generic types are by default invariant. Suppose, we have two List types of Scala i.e, S and T. where, S is sub-type of T but List[T] and List[S] are not at all related, then they fall under the invariant type.Syntax:List[T]Here, we don’t use any symbol for invariant relationship.Note: The classes like Array[T], ListBuffer[T], ArrayBuffer[T] etc. are mutable so, they have invariant type parameter, if we use invariant type parameters in inheritance relationship or sub-typing then we will get a compilation error.
List[T]
Here, we don’t use any symbol for invariant relationship.Note: The classes like Array[T], ListBuffer[T], ArrayBuffer[T] etc. are mutable so, they have invariant type parameter, if we use invariant type parameters in inheritance relationship or sub-typing then we will get a compilation error.
Picked
Scala
scala-parameterized-type
Scala
Technical Scripter
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Type Casting in Scala
Class and Object in Scala
Scala Tutorial – Learn Scala with Step By Step Guide
Scala Lists
Operators in Scala
Scala String substring() method with example
Scala | Arrays
Scala Constructors
Enumeration in Scala
Inheritance in Scala