2011-11-17 14 views
5

Teóricamente es sonido para reemplazar los métodos de uno de los padres en una subclase con un método en el que los parámetros son los supertipos de los parámetros de la clase padre, como:¿Hay lenguajes de programación de tipo estático con herencia donde los parámetros del método son contravariantes?

class T 
    def foo(s: String) = ... 

class S 
    override def foo(a: Any) = ... 

¿Qué lenguajes de programación son compatibles con esta "característica" y cómo Cómo se resuelven problemas como la posibilidad de que un solo método de una subclase puede anular múltiples métodos de una clase padre: (. Suponiendo que String y Int subtipos de Any)

class T 
    def foo(s: String) = ... 
    def foo(i: Int) = ... 

class S 
    override def foo(a: Any) = ... 

+0

Si habla de lenguajes tipados estáticos de lo que no sé. Los lenguajes de tipado dinámico no se preocupan por este problema, así que supongo que está hablando de lenguajes tipados estáticamente. Por favor, tenga en cuenta en su pregunta. –

+0

WIkipedia afirma que un lenguaje llamado "Sather" tiene una contravariancia (http://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29#Sather, http://en.wikipedia.org/wiki/Sather), pero yo no puede garantizar su precisión. –

+0

no conozco ese lenguaje, pero no veo ningún problema con el hecho de que un método puede anular múltiples métodos de superclase. cuando haces 'sInstance.foo (anyObject)' entonces se llama a este método. no 'T.foo (String)' ni 'T.foo (Int)'. No hay problema para el compilador. solo usted, como programador, tiene que diseñar sus clases, por lo que esta invocación tiene sentido – piotrek

Respuesta

0

Aunque entiendo los conceptos, no sé si entiendo completamente su pregunta. A saber, parece que estás diciendo que las clases derivadas deberían poder implementar reemplazos de métodos que usan parámetros que son 'menos' derivados. Eso me parece retrógrado. Parece que el método predominante solo debería poder usar 'más' tipos derivados. Tal vez eso es lo que quería decir, o tal vez estoy equivocado acerca de eso, pero he aquí un fragmento de lo que C# 4.0 permite:

(Tomado de http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx)

¿Cuál es la varianza para parámetros de tipo genérico? Esta es una nueva característica en C# 4.0. Ahora, al crear una interfaz genérica, puede especificar si hay una conversión implícita entre instancias de interfaz que tienen diferentes argumentos de tipo. Por ejemplo, puede usar una instancia de interfaz que tenga métodos con más tipos de devolución derivados que los especificados originalmente (covarianza) o que tenga métodos con menos tipos de parámetros derivados (contravarianza). Las mismas reglas se aplican a los delegados genéricos.

+1

"Eso me parece al revés", no lo es, es correcto. Si la función 'foo' en la clase base puede aceptar cualquier String, la anulación' foo' * must * como mínimo debe aceptar cualquier String, de lo contrario, rompe LSP. Lo que hace la contravarianza es permitir, además, aceptar otras cosas. Tomar un super-tipo de Cadena hace eso, permite Cadena y otras cosas. Es la otra cara de la covarianza del tipo de retorno, que dice que si una clase base promete devolver un String, entonces una clase derivada puede ser más específica sobre lo que devuelve y solo producir ciertos subtipos de String. –

+0

Ah, veo que no estaba leyendo mi propia cita correctamente. Veo que es exactamente lo que dice ahora. –

2

(Respuesta incompleta) Si tomamos el ejemplo de OCaml, responde al título de su pregunta: este es un "lenguaje de programación de tipo estático con herencia donde los parámetros del método son contravariantes".

En cuanto a la segunda parte de su pregunta ("cómo resuelven problemas como ..."), el nudo gordiano se corta al no permitir la sobrecarga. (Sobrecarga significa tener dos funciones con el mismo nombre pero diferentes tipos de argumentos, lo que hace que la inferencia de tipo sea mucho más difícil).

Cuestiones relacionadas