FeaturedNOTICIAS

¿Qué son la covarianza y la contravarianza en la programación? – CloudSavvy IT


Imagen abstracta que muestra los rectángulos amarillos en expansión

La covarianza y la contravarianza son términos que describen cómo un lenguaje de programación maneja los subtipos. La varianza de un tipo determina si sus subtipos se pueden usar indistintamente con él.

La varianza es un concepto que puede parecer opaco hasta que se proporcione un ejemplo concreto. Consideremos un tipo básico Animal con un subtipo de Dog.

interface Animal {
    public function walk() : void;
}
 
interface Dog extends Animal {
    public function bark() : void;
}

Todos los «animales» pueden caminar, pero sólo los «perros» pueden ladrar. Consideremos ahora qué sucede cuando se usa esta jerarquía de objetos en nuestra aplicación.

Interfaces de cableado juntas

Desde cada uno Animal podemos caminar, podemos crear una interfaz genérica que ejercite cualquier Animal.

interface AnimalController {
 
    public function exercise(Animal $Animal) : void;
 
}

los AnimalController tiene un exercise() método que indica el tipo de archivo Animal interfaz.

interface DogRepository {
 
    public function getById(int $id) : Dog;
 
}

Ahora tenemos un archivo DogRepository con un método que garantiza la devolución de un archivo Dog.

¿Qué sucede si intentamos usar este valor con la extensión AnimalController?

$AnimalController -> exercise($DogRepository -> getById(1));

Esto está permitido en idiomas donde se admiten parámetros covariantes. AnimalController debe recibir un Animal. Lo que estamos atravesando es en realidad un archivo Dog, pero aun así satisface el Animal contratar.

TE INTERESA>>  'Killing Eve' Confirms Netflix US Release Date for April 2024

Este tipo de relación es especialmente importante a la hora de extender lecciones. Puede que queramos un genérico AnimalRepository que recupera cualquier animal sin los detalles de su especie.

interface AnimalRepository {
 
    public function getById(int $id) : Animal;
 
}
 
interface DogRepository extends AnimalRepository {
 
    public function getById(int $id) : Dog;
 
}

DogRepository modifica el contrato de AnimalRepository– ya que las personas que llaman recibirán un Dog en lugar de un archivo Animal– Pero eso no cambia radicalmente. Es solo cuestión de ser más específico sobre su tipo de retorno. A Dog sigue siendo un Animal. Los tipos son covariantes, por lo tanto DogRepositoryLa definición de es aceptable.

Mirando la contravarianza

Consideremos ahora el ejemplo inverso. Puede ser deseable tener un DogController, que altera la forma en que se ejercitan los «perros». Lógicamente, esto aún podría extender el AnimalController interfaz. Sin embargo, en la práctica, la mayoría de los idiomas no le permitirán anular exercise() de la manera necesaria.

interface AnimalController {
 
    public function exercise(Animal $Animal) : void;
 
}
 
interface DogController extends AnimalController {
 
    public function exercise(Dog $Dog) : void;
 
}

En este ejemplo, DogController lo especificó exercise() acepta solo un Dog. Esto entra en conflicto con la definición anterior en AnimalController, que permite el paso de cualquier «Animal». Para cumplir el contrato, DogController debe, por tanto, aceptar también cualquier Animal.

A primera vista, esto puede parecer confuso e innecesario. El razonamiento detrás de esta restricción se vuelve más claro cuando se menciona contra AnimalController:

function exerciseAnimal(
    AnimalController $AnimalController,
    AnimalRepository $AnimalRepository,
    int $id) : void {
 
    $AnimalController -> exercise($AnimalRepository -> getById($id));
}

El problema es ese AnimalController podría ser un archivo AnimalController oa DogController—Nuestro método es no saber qué implementación de interfaz está utilizando. Esto se debe a las mismas reglas de covarianza que fueron útiles anteriormente.

TE INTERESA>>  La emotiva miniserie con Luis Tosar y Blanca Portillo que está arrasando en Netflix. Una aventura en alta mar basada en hechos reales

Me gusta AnimalController pudo ser un DogController, ahora hay un error de ejecución grave esperando ser descubierto. AnimalRepository siempre devuelve un Animal, Así que si $AnimalController es a DogController, la aplicación se bloqueará. los Animal el tipo es demasiado vago para pasar al archivo DogController exercise() método.

Vale la pena señalar que se aceptarían los idiomas que admitan la sobrecarga de métodos DogController. Overhead le permite definir varios métodos con el mismo nombre, siempre que tengan varios firmas (Tienen diferentes parámetros y / o tipos de retorno). DogController tendría un extra exercise() método que acepta sólo «Perros». Sin embargo, también debería implementar la firma ascendente que acepta cualquier «Animal».

Manejo de problemas de varianza

Todo lo anterior se puede resumir diciendo que los tipos devueltos por las funciones pueden ser covariante mientras que los tipos de argumentos deben ser contravariante. Esto significa que una función puede devolver un tipo más específico que el definido por la interfaz. También puede tomar un tipo más abstracto como argumento (aunque la mayoría de los lenguajes de programación populares no lo implementan).

Muy a menudo, se encuentran problemas de variación cuando se trabaja con genéricos y colecciones. En estos escenarios, a menudo desea un AnimalCollection está en DogCollection. Ellos deberían DogCollection ampliar AnimalCollection?

Así es como podrían verse estas interfaces:

interface AnimalCollection {
    public function add(Animal $a) : void;
    public function getById(int $id) : Animal;
}
 
interface DogCollection extends AnimalCollection {
    public function add(Dog $d) : void;
    public function getById(int $id) : Dog;
}

Mirando primero getById(), Dog es un subtipo de Animal. Los tipos son covariantes y se permiten los tipos devueltos covariantes. Esto es aceptable. Veamos de nuevo el problema de la varianza con add() aunque-DogCollection debe permitir cualquier Animal para ser agregado para satisfacer el AnimalCollection contratar.

TE INTERESA>>  1 Brilliant Halo Season 3 Theory Connects Kwan To This Forerunner Enemy

Este problema generalmente se resuelve mejor haciendo que las colecciones sean inmutables. Solo permite agregar nuevos elementos en el constructor de la colección. Luego puede eliminar el archivo add() método del conjunto, fabricación AnimalCollection un buen candidato para DogCollection para heredar.

Otras formas de varianza

Además de la covarianza y la contravarianza, también puede encontrar los siguientes términos:

  • Bivariante: Un sistema de tipos es bivariante si tanto la covarianza como la contravarianza se aplican simultáneamente a una relación de tipos. TypeScript utilizó la bivariancia para sus parámetros antes de TypeScript 2.6
  • Variante: Los tipos son variantes si se aplica covarianza o contravarianza.
  • Invariante: Todo tipo que no sea variantes.

Por lo general, trabajará con tipos covariantes o contravariantes. En términos de herencia de clases, un tipo B es covariante con un tipo A si es se extiende A. Un tipo B es contravariante con un tipo A si es el antepasado de B.

Conclusión

La varianza es un concepto que explica los límites dentro de los sistemas de tipos. Por lo general, es suficiente recordar que la covarianza se acepta en los tipos de retorno, mientras que la contravarianza se usa para los parámetros.

Las reglas de varianza se derivan del principio de sustitución de Liskov. Esto indica que debería poder reemplazar instancias de una clase con instancias de sus subclases sin afectar ninguna de las propiedades del sistema más grande. Esto significa que si el tipo B extiende el tipo A, las instancias de A se puede reemplazar con instancias de B.

Usar nuestro ejemplo anterior significa que debemos poder reemplazar Animal con Dog, o AnimalController con DogController. Aquí vemos la razón de nuevo DogController no se puede sobrescribir exercise() aceptar solo perros: ya no podríamos reemplazar AnimalController con DogController, como consumidores que actualmente superan un Animal ahora debería proporcionar un archivo Dog en vez de. La covarianza y la contravarianza dictan LSP y aseguran estándares consistentes de comportamiento.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

Botón volver arriba
hentai creampir hentairulz.com saoff summer xxxx hot zoztube.mobi xhamsted ماياخليفة سكس parabg.com سكس قذف جماعى سكس جنوب افريقيا arab-porno.net سكس بنات محجبة freefuck redwap2.com karnataka blue film نيك خادمة freetvtube.info قصص نيك محارم الارشيف 23 sexy rapes teenextube.mobi latest scandals in bollywood milf manga truehentai.com la blue girl manga ang probinsyano june 19 pinoyshowstv.com enchong pokemon henatai hentaicredo.com boku no pico nokare .com gotporn.mobi www.freesexdoor.com indian first night xxx pornxvideos.info xxx six india sex samantha sex zatube.mobi cuddling porn mom son sleeping sex hdtporno.org velamma episode 74 indian free porn mms youjizz.sex velamma episode 79