我有一个抽象类,有一个抽象方法。我如何使用lambda表达式来实例化它。它不能成为一个接口,因为它扩展了一个类。
public class Concrete<T> {
// Has a bunch of predefined methods.
}
public abstract class Abstract<T> extends Concrete<T> {
public T getSomething();
// Uses inherited methods from Concrete class
}
public class Driver {
public static void main(String[] args) {
System.out.println(new Abstract<String>() {
public String getSomething() {
// Returns something using inherited methods from Abstract
// Class and Concrete Class
}
});
}
}
答案 0 :(得分:45)
你不能直接将lambda表达式作为抽象类,正如Sleiman Jneidi在他的回答中指出的那样。但是,您可以使用解决方法:
public class AbstractLambda<T> extends Abstract<T>
{
private final Supplier<? extends T> supplier;
public AbstractLambda(Supplier<? extends T> supplier)
{
this.supplier = supplier;
}
@Override
public T getSomething()
{
return this.supplier.get();
}
}
这可以与lambda表达式一起使用:
Abstract<String> a = new AbstractLambda<>(() -> "Hello World");
System.out.println(a.getSomething()); // prints 'Hello World'
如果您的getSomething(...)
方法有参数,请使用java.util.function.Function
或java.util.function
包中的相应界面,而不是java.util.function.Supplier
。
这也是java.lang.Thread
允许你使用Runnable
lambda而不必使用类的子类的方法:
Thread t = new Thread(() -> System.out.println("Hello World"));
t.start();
答案 1 :(得分:37)
不,你不能这样做。 Lambdas必须在接口上定位单个抽象方法(SAM),并且它们不能在抽象类上使用单个抽象方法。这是怎么回事,你必须接受它,
尽管拥有它们是有意义的,但是语言设计者认为通过在SAM抽象类上允许lambdas来引入复杂性是不值得的。
As a reference, thats Brian Goetz所说的关于在SAM抽象类上允许lambdas的内容。
Brian的电子邮件主要关键点:
只有3%的lambda候选人 内部类实例将抽象类作为目标
使模型复杂化 几百%使用案例似乎是一个不好的交易
答案 2 :(得分:0)
同时,我们现在在接口中具有默认实现。我处于类似情况,尝试过抽象类。使用两种方法切换到接口,其中一种具有默认实现。 Java将接口标识为具有单个抽象方法,我可以使用lambda语法将接口的实现作为参数传递。
缺点是,如果有人真的坚持,可以通过在某些(匿名或非匿名)类中显式实现接口来覆盖具有默认实现的方法。而且您不能限制它,因为在接口上所有方法都是公共的。根据您的情况,可能没什么大不了的。