Esta pregunta es antigua, pero creo que una explicación más clara es invocar el Principio de sustitución de Liskov: todo lo que es cierto acerca de una superclase debería ser cierto para todas sus subclases. Debería poder hacer con un SubFoo todo lo que puede hacer con un Foo, y tal vez más.
Supongamos que tenemos Calico <: Gato <: Animal y Husky <: Perro <: Animal. Veamos un Function[Cat, Dog]
. ¿Qué afirmaciones son ciertas sobre esto? Hay dos:
(1) se puede pasar en cualquier gato (por lo que cualquier subclase de gato)
(2) Puede llamar a cualquier método de perro en el valor devuelto
Lo mismo sucede con sentido Function[Calico, Dog] <: Function[Cat, Dog]
maquillaje ? No, las afirmaciones que son verdaderas de la superclase no son verdaderas de la subclase, es decir, la declaración (1). No puedes pasar ningún gato a una función que solo tome gatos Calico.
¿Pero tiene sentido Function[Animal, Dog] <: Function[Cat, Dog]
? Sí, todas las afirmaciones sobre la superclase son verdaderas de la subclase. Todavía puedo pasar a cualquier gato; de hecho, puedo hacer aún más que eso, puedo pasar a cualquier animal, y puedo llamar a todos los métodos de perro en el valor devuelto.
Así A <: B
implica Function[B, _] <: Function[A, _]
Ahora bien, ¿Function[Cat, Husky] <: Function[Cat, Dog]
sentido? Sí, todas las afirmaciones sobre la superclase son verdaderas de la subclase; Todavía puedo pasar un Cat, y todavía puedo llamar a todos los métodos Dog en el valor devuelto; de hecho, puedo hacer incluso más que eso, puedo llamar a todos los métodos de Husky sobre el valor devuelto.
¿Pero tiene sentido Function[Cat, Animal] <: Function[Cat, Dog]
? No, las afirmaciones que son verdaderas de la superclase no son verdaderas de la subclase, es decir, la declaración (2). No puedo llamar a todos los métodos disponibles en Dog en el valor devuelto, solo los disponibles en Animal.
Así que con un Function[Animal, Husky]
puedo hacer todo lo que puedo hacer con un Function[Cat, Dog]
: puedo pasar cualquier Cat, y puedo llamar a todos los métodos Dog en el valor devuelto. Y puedo hacer aún más: puedo pasar otros animales, y puedo llamar a los métodos disponibles en Husky que no están disponibles en Dog. Entonces tiene sentido: Function[Animal, Husky] <: Function[Cat, Dog]
. El primer parámetro de tipo puede ser reemplazado por una superclase, el segundo con una subclase.
Gracias, eso fue muy claro. Intentar (re) definir: 'co/contra-varianza son propiedades que dictan la relación de subtipos entre tipos, sujetos a la naturaleza de la misma relación entre sus tipos de componentes'. Resumen, lo sé, pero prefiero tener una definición desprovista de ejemplos (aunque la tuya fue muy útil). – bjt38
gracias por la A, ¿podría explicar por qué es + B en la Función1 [-A, + B] – liango
@liango - Anexplicación por ejemplo: si devuelve un 'String' ciertamente devuelve un' Objeto', entonces '. .. => String' debe ser una subclase de '... => Object'. Eso es lo que significa '+ B'. –