在Java中接口是一种规范,接口本身不能实例化,实现了接口的类可以实例化。在实现了接口的类中,该类要实现接口中的抽象方法。
举个例子,定义一个接口 Printable,该接口只有一个抽象方法 print()。
public interface Printable {
void print();
}
定义一个类 Cat, 该类实现 Printable 接口。
public class Cat implements Printable{
public String name;
public int age;
public Cat(){}
@Override
public void print() {
System.out.println("喵~" );
}
}
不使用Lambda表达式:定义一个主类 Lambdas,定义一个静态方法 printThing。printThing方法接收一个实现了 Printable 接口 的对象,在 printThing方法中利用Java的动态绑定机制,调用实现了 Printable 接口 的对象中重写的print方法。为什么调用的是实现了接口的对象中重写的方法,需要了解Java中的动态绑定机制。在 main 方法中 new 一个Cat对象,将Cat对象作为实参传给 printThing。运行结果是在控制台打印出:喵~
不使用Lambda表达式,需要先定义一个实现了 Printable 接口的Cat类,需要在Cat类中重写Printable 接口定义的抽象方法print。然后需要 new 一个 cat 对象,调用 printThing方法时,将cat对象作为形参。需要这么多步骤,非常麻烦。
public class Lambdas {
public static void main(String[] args) {
Cat cat = new Cat();
printThing(cat);
}
static void printThing(Printable thing){
thing.print();
}
}
使用Lambda表达式:在调用 printThing 方法时,在()中使用 Lambda表达式重写了 Printable 中的抽象方法 print。因为Printable 是 函数式接口,所以不需要申明 print 方法的返回类型和参数类型,Java会自动判断。用Lambda表达式重写函数式接口中的抽象方法时,会隐式的创建一个实现了 Printable 接口的匿名对象,而 Lambda表达式就是在编写这个匿名对象的 print 方法。运行结果同样是:喵~
public class Lambdas {
public static void main(String[] args) {
printThing(
() -> {
System.out.println("喵~" );
}
);
}
static void printThing(Printable thing){
thing.print();
}
}
当函数式接口中的抽象方法有参数时,例如:
public interface Printable {
void print(String str);
}
这时,使用Lambda表达式:
public class Lambdas {
public static void main(String[] args) {
printThing(
(s) -> {
System.out.println("喵~" + s);
}
);
}
static void printThing(Printable thing){
thing.print(“!!!”);
}
}
运行结果是:喵~!!!
Lambda 表达式 中的()里面的方法参数不需要和 print()方法的参数名一样。
可以看出,使用Lambda表达式,和匿名内部类相似,不用再定一个实现类,重写接口中的方法,然后 new 一个实体对象了。只是Lambda表达式创建匿名对象的前提是,需要实现的接口是函数式接口(接口中只能有一个抽象方法)。这是我对Lambda表达式的理解,欢迎留言指正错误。