Scala – Contravarianza

La contravarianza es exactamente lo contrario de la covarianza. Contra-Variance crea una relación de subtipificación similar entre la clase y el parámetro de tipo. Entonces, la contravarianza establece que si hay dos tipos parametrizados tales que S es un subtipo de T, entonces List[T] es un subtipo de List[S]. Podemos hacer una contravariante de clase genérica usando la notación [-S]. Podemos usar la contravarianza siempre que el parámetro de tipo (genérico) «consume» el tipo S o los tipos que aceptan. También podemos usar contravariante como tipo de argumento de método, pero no como tipo de retorno de método porque generará un error de compilación.

Sintaxis:

List[-T]

Aquí, T es el parámetro de tipo y – es el símbolo de Contravarianza.

Ejemplo 1: Consideremos un ejemplo en el que Printer[S] es una clase que imprime algún tipo S. Definiremos aquí subclases para un tipo:

// Scala program to illustrate contra-variance 
  
abstract class Printer[-S] 
{  
    // Here -S denotes Contra-Variant 
    // type S
    def print(value: S): Unit
} 
  
abstract class Flower
{
    def name: String
}
  
// Create subclass of Flower
case class Lily(name: String) extends Flower
  
class FlowerPrinter extends Printer[Flower] 
{
    def print(flower: Flower): Unit =
      
    // Display name of flower
    println("The flower's name is: " + flower.name)
}
  
class LilyPrinter extends Printer[Lily] 
{
    def print(lily: Lily): Unit =
    println("Lily's name is: " + lily.name)
}
  
// Inherit the main method
object Contravariance extends App
{
      
    // Assign value    
    val lily : Lily = Lily("White Lily") 
  
    // Define method to print the name
    def printMyLily(printer: Printer[Lily]): Unit =
    {
        printer.print(lily)
    }
  
    // Create objects
    val lilyPrinter: Printer[Lily] = new LilyPrinter
    val flowerPrinter: Printer[Flower] = new FlowerPrinter
  
    printMyLily(lilyPrinter)
    printMyLily(flowerPrinter)
}

Producción:

Lily's name is: White Lily
The flower's name is: White Lily

Explicación: Aquí en este código, si una impresora [Lily] puede imprimir cualquier Lily y una impresora [Flower] puede imprimir una flor, entonces una Printer [Flower] también puede imprimir Lily. Pero no se puede hacer lo contrario ya que la Impresora [Lily] no sabe cómo imprimir ninguna Flor. Entonces, podemos usar Print[Flower] como una alternativa para Printer[Lily] y podemos hacerlo haciendo Printer[S] Contra-Variant.

Ejemplo 2: considere este ejemplo de vehículo de clase genérica:

// Scala program to illustrate contra-variance 
  
abstract class GetVehicleName[-S] 
{  
    // Here -S denotes Contra-Variant
    // type S
    def print(value: S): Unit
}
  
abstract class Vehicle
{
    def name: String
}
  
// Create subclass of Flower
case class Bike(name: String) extends Vehicle
  
class VehicleName extends GetVehicleName[Vehicle]
{
    def print(vehicle: Vehicle): Unit =
    println("The vehicle's name is: " + vehicle.name)
}
  
class BikeName extends GetVehicleName[Bike] 
{
    def print(bike: Bike): Unit =
    println("Bike's name is: " + bike.name)
}
  
// Inherit the main method
object Contravariance extends App
{
      
    // Assign value    
    val bike : Bike = Bike("Yamaha Fazer") 
  
    // Define method to print the name
    def printMyBike(getVehicleName: GetVehicleName[Bike]): Unit =
    {
        getVehicleName.print(bike)
    }
  
    // Create objects
    val bikeName: GetVehicleName[Bike] = new BikeName
    val vehicleName: GetVehicleName[Vehicle] = new VehicleName
  
    printMyBike(bikeName)
    printMyBike(vehicleName)
}

Producción :

Bike's name is: Yamaha Fazer
The vehicle's name is: Yamaha Fazer

Explicación: En este ejemplo, obtenemos el mismo resultado para ambos debido a la contravarianza. Como la clase abstracta Get_vehicle_name es contravariante, podemos reemplazar Get_vehicle_name[Vehicle] por Get_vehicle_name[Bike], pero no se permite la inversa.

Publicación traducida automáticamente

Artículo escrito por devanshigupta1304 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *