Hay dos cosas que suceden aquí:
- una función y un método are not the same thing
- métodos no son polimórficos en los tipos de sus parámetros
Su método tester
es un método , no es Function1
. Puede ser levantado en una función utilizando la sintaxis de subrayado:
val f = (new FooTest[String]).tester _ // Fasel => Bla
Esta función será contra-variante en su tipo de entrada. (Vale la pena decir, sin embargo, que las funciones no se pueden parametrizar y también vale la pena decir que tuve que tener una instancia de Foo
o FooTest
para obtener un objeto de función para el método tester
. Esto, por supuesto, se sigue de la primera observación!)
Una función es un objeto, no se puede anular ya que no tiene sentido. Los métodos pueden ser anulados. Sin embargo, como dije antes, la anulación no es polimórfica en los tipos de parámetros del método. Así, por ejemplo:
class A {
def foo(a : Any) = println("A: " + a)
}
class B extends A {
override def foo(s : String) = println("B " + s) //will not compile!
}
los dos métodos en el ejemplo anterior son dos métodos distintos: envío dinámico sólo funciona en el objetivo método (es decir, el objeto sobre el que está siendo llamado).
En el ejemplo anterior, si elimina la declaración override
, se compilará el código. Si ejecuta el siguiente:
(new B).foo(1) //prints A 1
(new B).foo("s") //prints B s
Esto es debido a que, aunque ambos métodos se llaman foo
, son completamente diferentes métodos (es decir, he sobrecargado foo
, no se reemplaza ella).Se entiende mejor como que los argumentos de un método '(incluidos sus tipos) forman parte del nombre único de ese método. Un método prevalece sobre otro solo si tienen exactamente el mismo nombre .
Esencialmente usted ha confundido lo que son dos independiente y cosas en su pregunta, que voy a poner abajo para mayor claridad relacionados con la ONU:
- Las anotaciones de varianza en
Function1
definen lo que significa para una función es un subtipo de otro (y por lo tanto asignable a una referencia de un tipo dado).
- Los métodos se pueden anular en las subclases y la especificación del lenguaje describe las reglas para cuando ocurre dicha anulación.
¿Dónde puedo leer esto en la referencia de scala? Solo por el hecho de ser completo :) – raichoo
Entendido: 3.3.1 MethodTypes Gracias :) – raichoo
He agregado un enlace a una pregunta sobre la comparación de método/función. Además, el bit sobre anulación de método es parte de la definición de bytecode (es decir, la especificación de formato de archivo de clase). Aunque espero que el lenguaje Scala especifique cómo se "levanta" un método scala en un método de bytecode. –