frostbite
frostbite

Reputation: 648

Lambda expressions for interface with multiple methods

Monkeying around with Java 8 lambdas. Why does this give me an error when I add another method to my interface:

      interface Something {
  public String doit(Integer i);
  public int getID(String name);.....

        Something s = (Integer i) -> {
        return i.toString();
    };
    System.out.println(s.doit(4));

    Something y = (Integer i) -> {
        return "do nothing";
    };
    System.out.println(y.doit(4));

Works fine without the second method: "public int getID(String name)

Upvotes: 1

Views: 4580

Answers (1)

nanofarad
nanofarad

Reputation: 41281

Java lambdas and method references may only be assigned to a functional interface. From Java SE 8 API, description of java.util.function package:

Each functional interface has a single abstract method, called the functional method for that functional interface, to which the lambda expression's parameter and return types are matched or adapted. Functional interfaces can provide a target type in multiple contexts, such as assignment context, method invocation, or cast context:

JLS 9.8 also discusses this:

A functional interface is an interface that has just one abstract method (aside from the methods of Object), and thus represents a single function contract. This "single" method may take the form of multiple abstract methods with override-equivalent signatures inherited from superinterfaces; in this case, the inherited methods logically represent a single method.

For an interface I, let M be the set of abstract methods that are members of I that do not have the same signature as any public instance method of the class Object. Then, I is a functional interface if there exists a method m in M for which both of the following are true:

  • The signature of m is a subsignature (§8.4.2) of every method's signature in M.

  • m is return-type-substitutable (§8.4.5) for every method in M.

In addition to the usual process of creating an interface instance by declaring and instantiating a class (§15.9), instances of functional interfaces can be created with method reference expressions and lambda expressions (§15.13, §15.27).

An interesting effect occurs with generics:

In the following interface hierarchy, Z is a functional interface [emphasis mine] because while it inherits two abstract methods which are not members of Object, they have the same signature, so the inherited methods logically represent a single method:

interface X { int m(Iterable<String> arg); }
interface Y { int m(Iterable<String> arg); }
interface Z extends X, Y {}

Upvotes: 5

Related Questions