2017-05-27 88 views
1

我努力学习Lambda表达式,的Java 8 Lambda表达式 - 方法重载怀疑

interface MathOperartor已运行()重载类型int和float,我敢肯定这应该是可能使用Lambda表达式做,但不能完全似乎要弄清楚是什么问题在这里:

public static void main(String[] args) { 
    LambdaLearning lb = new LambdaLearning(); 

    MathOperartor add = (a , b)-> a + b; // error: The target type of this expression must be a functional interface 
    MathOperartor sub = (a , b) -> a - b; // same error 
    MathOperartor mul = (a , b) -> a * b; // '' 
    MathOperartor div = (a , b) -> a/b; // '' 

    System.out.println(lb.operate(10, 15, add)); 
    System.out.println(lb.operate(10.5f, 15.5f, sub)); 
    System.out.println(lb.operate(10, 15, mul)); 
    System.out.println(lb.operate(10, 15, div)); 

} 

interface MathOperartor{ 
    public Object operate(int a, int b); 
    public Object operate(float a, float b); 
} 

private Object operate(int a, int b, MathOperartor math){ 
    return math.operate(a,b); 
} 
private Object operate(float a, float b, MathOperartor math){ 
    return math.operate(a,b); 
} 

请让我知道我在做什么错在这里,并提出修复...

更新:

好吧,所以我理解了功能接口的概念,我的问题也是关于在上面的代码中实现我想要做的事情,并且找到了几种方法来实现它。

谢谢你们每一位的宝贵答案!

+4

您需要在该接口中只有一个抽象方法,查找功能接口。 – halil

+2

“这个表达式的目标类型必须是一个函数接口”=>呃...类型'MathOperartor'不是[函数接口](http://docs.oracle.com/javase/specs/jls/se8 /html/jls-9.html#jls-9.8)。 – Seelenvirtuose

+4

[Java 8中的函数接口的用途是什么?](https://stackoverflow.com/questions/36881826/what-is-use-of-functional-interface-in-java-8) – Seelenvirtuose

回答

6

functional interface必须是一个SAM接口:

功能接口都只有一个抽象方法。由于默认方法有一个实现,它们不是抽象的。如果一个接口声明一个抽象方法覆盖java.lang.Object的一个公共方法,那么它也不会计入接口的抽象方法计数,因为接口的任何实现都会从java.lang.Object或其他地方实现。

你的界面已经宣布2种抽象方法的lambda表达式不知道要去哪里,和lambda表达式是接口的实例,这意味着必须实现所有接口中声明的抽象方法。但你可以添加默认方法解决你的问题在这种情况下,例如:

interface MathOperartor{ 
    //it also can be removed, since a int can cast to a float automatically 
    default Object operate(int a, int b){ 
    return operate((float)a, (float)b); 
    } 
    public Object operate(float a, float b); 
} 
+0

谢谢!这解释了我的疑问,并解决了代码中的错误。 – Balu

+2

@Balu一点都没有。这是我的荣幸。 –

2

功能界面可以有一个抽象方法不多说。

3

一般其他的答案是正确的,即一个@FunctionalInterface是一个具有抽象方法,除了Object中声明的那些。这仍然是合法的:

@FunctionalInterface 
    static interface Testable { 

     public abstract String toString(); 

     public abstract void test(); 
    } 
3

函数接口中的lambda目标也被称为SAM(单抽象方法)接口。 以下是你如何可以运行你的例子:

@FunctionalInterface 
public interface MathOperator<T> { 
    T operate(T a,T b); 
} 

public class MathOperations { 
    public static void main(String[] args) { 

     MathOperator<Integer> add = (a, b) -> a + b; 
     MathOperator<Integer> sub = (a, b) -> a - b; 

     System.out.println(add.operate(1, 2)); 
     System.out.println(sub.operate(2, 1)); 

    } 

} 

希望它会帮助你

+0

谢谢!还有一种方法可以解决我的错误:) – Balu

2

用来表示一个接口类型的声明意在功能接口的信息注释类型。

功能接口只有一个抽象方法。由于默认方法有一个实现,它们不是抽象的。如果一个接口声明一个抽象方法覆盖java.lang.Object的一个公共方法,那么它也不会计入接口的抽象方法计数,因为接口的任何实现都会从java.lang.Object或其他地方实现。

实施例:

@FunctionalInterface 
public interface SimpleFuncInterface { 
    public void doWork(); 
} 

但是,一个接口可具有一个抽象方法,但任何数量的默认方法和接口将仍然被称为功能接口。

实施例:

所以,您的代码将被转换为:的功能接口

interface MathOperartor { 

    default Object operate(int a, int b) { 
     return operate((float) a, (float) b); 
    } 

    public Object operate(float a, float b); 

} 

实例可以与lambda表达式,方法引用,或构造的引用来创建。

但是,编译器会将满足功能接口定义的任何接口视为功能接口,而不管接口声明中是否存在FunctionalInterface注释。

+0

谢谢。这是非常丰富的。 – Balu