简体   繁体   中英

How to use lambdas for interfaces with multiple methods?

Is there a way to use lambdas if the target class has more than one interface methods? Or do you just have to use an anonymous inner class in that case?

No, there isn't. If I understood your question correctly you'd want to use lambdas for interfaces with more than one abstract method. In that case the answer is negative:

A functional interface is any interface that contains only one abstract method . (A functional interface may contain one or more default methods or static methods.) Because a functional interface contains only one abstract method, you can omit the name of that method when you implement it. To do this, instead of using an anonymous class expression, you use a lambda expression [...]

Read it up there: http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

It is not possible to directly create a multi-method object with a lambda.

But, you can use a work-around to solve the problem in a pretty neat way:

Use a util method that takes a number of single-method objects as arguments, and returns a multi-method object, into which the single-method objects have been packed.

Example:

interface MultiMethodInterface {
    void method1();
    String method2(String arg);
}

public static void example() {
    // One lambda for each method, they are packed into a 
    // MultiMethodInterface object by the multiMethodInterface method
    MultiMethodInterface i1 = createMultiMethodObject(
            () -> System.out.println("method1"),
            arg -> "method2: " + arg);

    // Sometimes only one of the methods is used, a specialized wrapper
    // can be used if that is common
    MultiMethodInterface i2 = 
            createMethod1Wrapper(() -> System.out.println("method1"));
}

public static MultiMethodInterface createMultiMethodObject(
        Runnable methodAction1,
        Function<String, String> methodAction2)
{
    return new MultiMethodInterface() {
        @Override
        public void method1() {
            methodAction1.run();
        }
        @Override
        public String method2(String arg) {
            return methodAction2.apply(arg);
        }
    };
}

public static MultiMethodInterface createMethod1Wrapper(Runnable methodAction1) {
    return createMultiMethodObject(methodAction1, arg -> "");
}

The resulting code is at least a bit shorter and prettier than to create a anonymous class. At least if the method implementations are short, and/or only one of the methods needs to be implemented.

This technique is used for example in the SWT toolkit , to create listener objects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM