这里发生了两件事:
- 一个函数和一个方法不是同一件事 https://stackoverflow.com/questions/2529184/difference-between-method-and-function-in-scala
- 方法的参数类型不是多态的
Your tester
方法是方法,not a Function1
。可以使用下划线语法将其提升为函数:
val f = (new FooTest[String]).tester _ // Fasel => Bla
该函数的输入类型将是逆变的。 (不过,值得一提的是,该功能无法参数化还值得一提的是我必须有一个实例Foo
or FooTest
为了获得一个函数对象tester
方法。这当然是根据第一次观察得出的!)
函数是一个对象,它不能被覆盖因为那没有意义。方法可以被重写。然而,正如我上面所说,重写在方法的参数类型中不是多态的。例如:
class A {
def foo(a : Any) = println("A: " + a)
}
class B extends A {
override def foo(s : String) = println("B " + s) //will not compile!
}
上面示例中的两个方法是两个独立的方法:动态调度仅适用于方法目标(即调用它的对象)。
在上面的示例中,如果删除override
声明,代码将编译。如果您运行以下命令:
(new B).foo(1) //prints A 1
(new B).foo("s") //prints B s
这是因为,虽然这两种方法都被称为foo
,它们是完全不同的方法(即我有超载 foo
, not 被覆盖它)。最好将其理解为方法的参数(包括它们的类型)构成该方法的唯一参数的一部分name。仅当一种方法完全相同时才会覆盖另一种方法name.
本质上你混淆了两个是什么分离且不相关的为了清楚起见,我将把你的问题中的内容写下来:
- 方差注释
Function1
定义一个函数作为另一个函数的子类型意味着什么(因此可分配的到给定类型的引用)。
- 可以在子类上重写方法,并且语言规范概述了何时发生此类重写的规则。