Java方法不能与Lambda表达式一起应用

时间:2018-09-10 10:11:02

标签: java lambda java-8 override functional-interface

我已经观看并阅读了https://caveofprogramming.com/java/whats-new-in-java-8-lambda-expressions.html,并且遵循了与运行转轮对象相同的模式,效果很好。

Runner runner = new Runner();
runner.run(() -> System.out.println("Print from Lambda expression"));

然后,我尝试创建一个简单的界面和类以应用我所学的知识。我只想用lambda表达式替换匿名类。我的理解是,lambda表达式是匿名类的较短代码,可提高可读性。

因此,我尝试启动另一个名为eucalyptus1的实例,并尝试@Override的{​​{1}}方法,但是我的IDE错误消息说:

  grow()中的

grow()无法应用于com.smith.Eucalyptus

有人可以指出我对这里的误解吗?

代码如下:

(lambda expression)

3 个答案:

答案 0 :(得分:10)

区别在于,您试图覆盖Eucalyptus的实现,该实现是实现接口的类。

Eucalyptus eucalyptus1 = new Eucalyptus();
eucalyptus1.grow(() -> System.out.println("This from Lambda expression")); 
^__  // you cannot override a method using an instance of a class which is just an implementation of the interface

您最终要做的就是传递一个lambda参数,当然,如果在方法调用时提供了一个没有参数的方法,则该方法的定义将无法编译。


相反,您可以将lambda的实现方式比较为:

//Anonymous class Myrtle from Plant interface
Plant myrtle = new Plant() {
          @Override
          public void grow() {
               System.out.println("This was running from anonymous class from Plant Interface");
          }
};
myrtle.grow();

可以表示为lambda表示形式:

Plant lambdaRep =  () -> System.out.println("This is running via lambda from Plant Interface");
lambdaRep.grow();

答案 1 :(得分:10)

问题

方法grow不带任何参数,因此会出现编译错误。

说明

lambda () -> System.out.println("This from Lambda expression")本身可以表示一个Plant(不是Eucalyptus *)实例:

Plant plant = () -> System.out.println("This from Lambda expression");
  

尝试从Plant界面创建Lambda表达式,并通过打印grow()通过覆盖"This was running from Lambda expression"方法

这里有些误解。不应该让Lambda 覆盖方法,这取决于提供基于@FunctionalInterface类型的方法


*如果要通过lambda定义Eucalyptus对象,将是模棱两可且不清楚lambda将代表什么方法。因此,禁止(even for abstract classes with a single abstract method.)

答案 2 :(得分:7)

您在这里使用的lambda表达式不正确。

您使用lambda表达式实现接口。在这种情况下,您将使用lambda表达式提供Plant的实现,而不是使用lambda表达式调用该接口的方法:

这是正常使用情况:

Plant eucalyptus1 = () -> System.out.println("This from Lambda expression");
eucalyptus1.grow(); // Prints "This from Lambda expression"

换句话说,由于您具有功能接口,因此应该能够避免创建实现该接口的类(无论是否匿名)。

因此,您完全不需要创建Eucalyptus类。