无法用lambda覆盖scala抽象函数

时间:2018-05-23 16:32:22

标签: 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

为什么?

2 个答案:

答案 0 :(得分:3)

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

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

因此,a中的方法Bbb包含错误的参数数量和不同的返回类型。

它不应该编译,因此它不会编译。没问题。

一般性评论:

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

不是

的语法糖
val f = (x1: T1, ..., xn: Tn): Y => body

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

答案 1 :(得分:2)

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

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

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

如果你真的需要一个函数值而不是一个方法,你需要声明另一个val并使用 eta-expansion ,如下所示:

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

b现在可以作为函数参数传递给filter等调用,而a则不能。