无法使用 lambda 覆盖 scala 抽象函数



如果我写:

trait Aaa { 
def a(i: Int): Boolean 
}
class Bbb extends Aaa { 
def a = (x: Int) => x == 42 
}

但是它无法编译,我收到以下错误:

override.scala:7: class Bbb needs to be abstract, since method a in trait Aaa of type (i: Int)Boolean is not defined
class Bbb extends Aaa {
^
Compilation Failed

为什么?

特征Aaa规定必须有一个方法a,其中包含一个类型为Int的参数并返回类型Boolean

Bbb有一个不带任何参数的方法a,返回类型(Int => Boolean),这与Function1[Int, Boolean]相同。

因此,Bbba的方法具有错误的参数数和不同的返回类型。

它不应该编译,所以它不会编译。没有任何问题。


一般评论:

def f(x1: T1, ..., xn: Tn): Y = body

不是句法糖

val f = (x1: T1, ..., xn: Tn): Y => body

前者是方法,后者是类型为FunctionN[T1, ..., Tn, Y]的值。虽然这两个定义在受ML影响的其他一些语言中可能以相同的方式处理,但在Scala中并非如此。Scala 区分方法和函数。

特征Aaa定义方法a但类Bbb定义函数a。方法与函数值不同是 Scala,因此类Bbba的定义不会实现Aaa中的a。由于Aaa.a没有定义,因此必须将类声明为abstract

如果您改为这样做,它将起作用:

class Bbb extends Aaa {
def a(x:Int) = x == 42
}

如果你真的需要一个函数值而不是一个方法,你需要声明另一个val并使用像这样的eta 扩展

class Bbb extends Aaa {
def a(x:Int) = x == 42
val b = a _
}

b现在可以作为函数参数传递给诸如filter之类的调用,而a则不能。

最新更新