我已经观看并阅读了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)
答案 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
类。