我认为这个问题已经存在,但我无法找到它.
我不明白,为什么有必要使用功能界面来处理lambdas.请考虑以下示例:
public class Test {
public static void main(String...args) {
TestInterface i = () -> System.out.println("Hans");
// i = (String a) -> System.out.println(a);
i.hans();
// i.hans("Hello");
}
}
public interface TestInterface {
public void hans();
// public void hans(String a);
}
Run Code Online (Sandbox Code Playgroud)
这没有问题,但如果您取消注释注释行,它不会.为什么?在我的理解中,编译器应该能够区分这两种方法,因为它们具有不同的输入参数.为什么我需要一个功能界面并炸毁我的代码?
编辑:链接重复项没有回答我的问题,因为我问的是不同的方法参数.但是我在这里得到了一些非常有用的答案,感谢所有帮助过的人!:)
编辑2:对不起,我显然不是母语人士,但为了准确自己:
public interface TestInterface {
public void hans(); //has no input parameters</br>
public void hans(String a); //has 1 input parameter, type String</br>
public void hans(String a, int b); //has 2 input parameters, 1. type = String, …Run Code Online (Sandbox Code Playgroud) 在Java中,使用lambda而不是匿名类可以优雅地实现具有单个抽象方法(即SAM类型或功能接口)的接口:
// SAM ActionListener with anonymous implementation
button.addActionListener(
new ActionListener(){
public void actionPerformed(Event e){
System.out.println("button via anon!");
}
}
);
Run Code Online (Sandbox Code Playgroud)
可以替换为:
// SAM ActionListener with lambda implementation
button.addActionListener(
e -> System.out.println("button via lambda!")
);
Run Code Online (Sandbox Code Playgroud)
但对于具有多个抽象方法的接口,无法直接应用lambda.例如,java.awt.event.WindowListener有七种方法.但通常一块代码只对定义这七种方法中的一种感兴趣.
要使用匿名类覆盖来实现该行为,我们可以:
// non-SAM with adapter implementation with override
window.addWindowListener(
new WindowAdapter() {
@Override
public void windowOpened(Event e){
System.out.println("WindowAdapter opened via override!");
}
}
);
Run Code Online (Sandbox Code Playgroud)
但是有一个更优雅的方式与lambdas?
@FunctionalInterface
public interface ActionListener {
void actionPerformed(Event e);
}
public interface WindowListener {
void windowOpened(Event e);
void windowClosing(Event …Run Code Online (Sandbox Code Playgroud) 我使用的界面看起来像这样:
public interface ObjectListener {
public void objectAdded(Object o);
public void objectRemoved(Object o);
}
Run Code Online (Sandbox Code Playgroud)
我目前正在使用匿名类来实现接口,但我不关心这两种方法中的一种.有点像这样:
someObject.addListener(new ObjectListener() {
@Override
public void objectAdded(Object o) {
doSomething(o);
}
@Override
public void objectRemoved(Object o) {}
});
Run Code Online (Sandbox Code Playgroud)
现在,无论我在哪里,我都在Java 8中使用新的lambda表达式,并且我希望在这种情况下使用增加的简单性.毕竟,我只是实现了其中一个方法,但由于接口中有两个方法,我不能在lambda表达式中使用它.
有没有办法解决这个限制?
假设我有接口A,它只有一个声明如下的方法:
interface A{
void print();
}
Run Code Online (Sandbox Code Playgroud)
现在使用旧的java风格,我们将以匿名的方式使用它,如下所示:
new A() {
@Override
public void print() {
System.out.println("in a print method");
}
};
Run Code Online (Sandbox Code Playgroud)
并使用lambda表达式,我们将使用它如下:
() -> "A1";
Run Code Online (Sandbox Code Playgroud)
现在我的问题是,如果接口A有两个声明如下的方法:
interface A{
void print();
void display();
}
Run Code Online (Sandbox Code Playgroud)
它以前的匿名函数利用方式如下:
new A() {
@Override
public void print() {
System.out.println("in print");
}
@Override
public void display() {
System.out.println("in display");
}
};
Run Code Online (Sandbox Code Playgroud)
现在如何将显示方法转换为lambda?或者我们不被允许这样做; 如果不是为什么不呢?为什么我们不能代表它
print() - >"打印"
和
display() - >"显示"