rai*_*hoo 5 inheritance overriding scala variance
我在解决重载时方法的方差方面遇到了一些问题.
虽然由于返回类型的协方差,这完美地起作用
class Bla
class Fasel extends Bla
trait Test[A] {
def tester(): Bla = new Bla
}
class FooTest[A](a: A) extends Test[A] {
override def tester(): Fasel = new Fasel
}
Run Code Online (Sandbox Code Playgroud)
即使函数在参数类型中是逆变的,这个也会失败.
class Bla
class Fasel extends Bla
trait Test[A] {
def tester(a: Fasel): Bla = new Bla
}
class FooTest[A](a: A) extends Test[A] {
override def tester(a: Bla): Fasel = new Fasel
}
Run Code Online (Sandbox Code Playgroud)
我在这里弄错了什么?有什么指针吗?
问候,raichoo
oxb*_*kes 11
这里有两件事:
你的tester方法是一种方法,而不是一种Function1方法.可以使用下划线语法将其提升为函数:
val f = (new FooTest[String]).tester _ // Fasel => Bla
Run Code Online (Sandbox Code Playgroud)
此功能在其输入类型中将具有矛盾的变体.(值得一提的是,函数不能参数化,也值得说我必须有一个实例Foo或者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!
}
Run Code Online (Sandbox Code Playgroud)
上面我的例子中的两个方法是两个独立的方法:动态调度仅适用于方法目标(即调用它的对象).
在上面的示例中,如果删除override声明,代码将被编译.如果您运行以下内容:
(new B).foo(1) //prints A 1
(new B).foo("s") //prints B s
Run Code Online (Sandbox Code Playgroud)
这是因为,尽管两种方法都被调用foo,但它们是完全不同的方法(即我已经过载 foo,没有重写它).最好的理解是方法的参数'(包括它们的类型)构成该方法唯一名称的一部分.一种方法只有在具有完全相同的名称时才会覆盖另一种方法.
基本上你已经混淆了你的问题中的两个独立和不相关的东西,为了清楚起见我将放下:
Function1定义了一个函数作为另一个函数的子类型意味着什么(因此可赋予给定类型的引用).