Lambda expressions are only usable with functional interface as said by Eran but if you really need multiple methods within the interfaces, you may change the modifiers to default or static and override them within the classes that implement them if necessary.
public class Test {
public static void main(String[] args) {
I1 i1 = () -> System.out.println(); // NOT LEGAL
I2 i2 = () -> System.out.println(); // TOTALLY LEGAL
I3 i3 = () -> System.out.println(); // TOTALLY LEGAL
}
}
interface I1 {
void show1();
void show2();
}
interface I2 {
void show1();
default void show2() {}
}
interface I3 {
void show1();
static void show2 () {}
}
Inheritance
You shouldn't forget the inherited methods.
Here, I2 inherits show1 and show2 and thus can not be a functional interface.
public class Test {
public static void main(String[] args) {
I1 i1 = () -> System.out.println(); // NOT LEGAL BUT WE SAW IT EARLIER
I2 i2 = () -> System.out.println(); // NOT LEGAL
}
}
interface I1 {
void show1();
void show2();
}
interface I2 extends I1 {
void show3();
}
Annotation
To make sure your interface is a functional interface, you may add the following annotation @FunctionalInterface
@FunctionalInterface <------- COMPILATION ERROR : Invalid '@FunctionalInterface' annotation; I1 is not a functional interface
interface I1 {
void show1();
void show2();
}
@FunctionalInterface
interface I2 {
void show3();
}
Answer from Yassin Hajaj on Stack OverflowLambda expressions are only usable with functional interface as said by Eran but if you really need multiple methods within the interfaces, you may change the modifiers to default or static and override them within the classes that implement them if necessary.
public class Test {
public static void main(String[] args) {
I1 i1 = () -> System.out.println(); // NOT LEGAL
I2 i2 = () -> System.out.println(); // TOTALLY LEGAL
I3 i3 = () -> System.out.println(); // TOTALLY LEGAL
}
}
interface I1 {
void show1();
void show2();
}
interface I2 {
void show1();
default void show2() {}
}
interface I3 {
void show1();
static void show2 () {}
}
Inheritance
You shouldn't forget the inherited methods.
Here, I2 inherits show1 and show2 and thus can not be a functional interface.
public class Test {
public static void main(String[] args) {
I1 i1 = () -> System.out.println(); // NOT LEGAL BUT WE SAW IT EARLIER
I2 i2 = () -> System.out.println(); // NOT LEGAL
}
}
interface I1 {
void show1();
void show2();
}
interface I2 extends I1 {
void show3();
}
Annotation
To make sure your interface is a functional interface, you may add the following annotation @FunctionalInterface
@FunctionalInterface <------- COMPILATION ERROR : Invalid '@FunctionalInterface' annotation; I1 is not a functional interface
interface I1 {
void show1();
void show2();
}
@FunctionalInterface
interface I2 {
void show3();
}
Lambda expressions can only be used to implement functional interfaces, which are interfaces having a single abstract method. An interface with two abstract methods can't be implemented by a lambda expression.
java - Why do I need a functional Interface to work with lambdas? - Stack Overflow
[Java] Can someone explain how interfaces work with arrow functions?
How does Java type check a program containing lambda expressions and default methods?
Why does the List interface have forEach, but not map?
What is a lambda expression in Java?
What is the syntax of a Java lambda expression?
How do method references work in Java?
When you write :
TestInterface i = () -> System.out.println("Hans");
You give an implementation to the void hans() method of the TestInterface.
If you could assign a lambda expression to an interface having more than one abstract method (i.e. a non functional interface), the lambda expression could only implement one of the methods, leaving the other methods unimplemented.
You can't solve it by assigning two lambda expressions having different signatures to the same variable (Just like you can't assign references of two objects to a single variable and expect that variable to refer to both objects at once).
The most important reason why they must contain only one method, is that confusion is easily possible otherwise. If multiple methods were allowed in the interface, which method should a lambda pick if the argument lists are the same ?
interface TestInterface {
void first();
void second(); // this is only distinguished from first() by method name
String third(); // maybe you could say in this instance "well the return type is different"
Object fourth(); // but a String is an Object, too !
}
void test() {
// which method are you implementing, first or second ?
TestInterface a = () -> System.out.println("Ido mein ado mein");
// which method are you implementing, third or fourth ?
TestInterface b = () -> "Ido mein ado mein";
}