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