为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

牧羊人nacy 2021-09-12 15:27:57
我已经观看并阅读了https://caveofprogramming.com/java/whats-new-in-java-8-lambda-expressions.html并且我遵循与运行正常的 runner 对象相同的模式。Runner runner = new Runner();runner.run(() -> System.out.println("Print from Lambda expression"));然后,我尝试创建一个简单的界面和类来应用我学到的知识。我只想用 lambda 表达式替换匿名类。我的理解是 lambda 表达式是匿名类的较短代码并提高可读性。因此,我尝试启动另一个调用的实例eucalyptus1并尝试使用@Override该grow()方法,但我的 IDE 错误消息说:grow()incom.smith.Eucalyptus不能应用于(lambda expression)谁能指出我在这里误解了什么?代码如下:// a simple interfaceinterface Plant {    public void grow();}// apply interface to classclass Eucalyptus implements Plant {    @Override    public void grow() {        System.out.println("This is from Eucalyptus");    }}public class Main {    public static void main(String[] args) {        // Create an instance of Eucalyptus        Eucalyptus eucalyptus = new Eucalyptus();        eucalyptus.grow();        // 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();        // Try to create a lambda expression from Plant interface        // and override grow() method        // by print ("This was running from Lambda expression")        // this won't work. why?        Eucalyptus eucalyptus1 = new Eucalyptus();        eucalyptus1.grow(() -> System.out.println("This from Lambda expression"));    }}
查看完整描述

3 回答

?
潇湘沐

TA贡献1816条经验 获得超6个赞

问题

该方法grow不接受任何参数,因此出现编译错误。

解释

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

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

尝试从Plant接口创建 lambda 表达式并通过 print覆盖grow()方法"This was running from Lambda expression"

这里有一个小小的误会。一个 lambda 不应该覆盖一个方法,它取决于提供一个基于@FunctionalInterface类型的方法


*如果您要Eucalyptus通过 lambda定义一个对象,那么 lambda 将代表什么方法将是模棱两可的并且不清楚。因此,它是被禁止的(即使对于具有单个抽象方法的抽象类。)


查看完整回答
反对 回复 2021-09-12
?
长风秋雁

TA贡献1757条经验 获得超7个赞

不同之处在于您试图覆盖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();


查看完整回答
反对 回复 2021-09-12
?
萧十郎

TA贡献1815条经验 获得超13个赞

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


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


这是一个正常的使用:


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

eucalyptus1.grow(); // Prints "This from Lambda expression"

换句话说,因为你有一个函数式接口,你应该能够避免创建实现它的类(匿名与否)。


所以你根本不需要创建这个Eucalyptus类。


查看完整回答
反对 回复 2021-09-12
  • 3 回答
  • 0 关注
  • 153 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信