java lambda表达式、匿名类和接口
从匿名类重写已有类的方法开始
这段代码,在AnonymousDemo内部创建了一个Polygon类的p1对象
但这个Polygon类内部的方法被重写了,是一个匿名类,内部类和外部类重名,重写了内部的方法
这个机制应该理解为继承,内部的Polygon继承了外部的Polygon类,重写了display方法,Polygon的其他没被重写的方法应该也在内部类中,所以应该理解为继承
class Polygon {
public void display() {
System.out.println("在 Polygon 类内部");
}
}
class AnonymousDemo {
public void createClass() {
// 内部类继承外部同名类并重写display方法
Polygon p1 = new Polygon() {
public void display() {
System.out.println("在匿名类内部。");
}
};
p1.display();
}
}
class Main {
public static void main(String[] args) {
AnonymousDemo an = new AnonymousDemo();
an.createClass();
}
}
按照这个机制,就可以重写接口了,与外部接口重名的内部匿名接口
interface Polygon {
public void display();
}
class AnonymousDemo {
public void createClass() {
// 匿名类实现一个接口
Polygon p1 = new Polygon() {
public void display() {
System.out.println("在匿名类内部。");
}
};
p1.display();
}
}
class Main {
public static void main(String[] args) {
AnonymousDemo an = new AnonymousDemo();
an.createClass();
}
}
Lambda表达式入场
给Thread传递函数参数,Lambda表达式()-> {/*某代码*/}
是一个函数
先前一直是以传递了函数指针的角度来理解的
public class test {
public static void main(String[] args) {
Thread thread = new Thread(()-> {/*某代码*/});
thread.start();
}
}
从匿名类的角度来看,Thread构造函数需要一个Runnable的对象,相当于重写了Thread类中的内部类Runnable
public class test {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
/*耗费时间的代码*/
}
});
thread.start();
}
}
如何使用Lambda简化呢
先来一个匿名类代码,匿名类实现了IEat接口的eat方法
public class test {
//此方法调用了IEat接口中的eat方法
public static void personEat(IEat e)
{
e.eat("蔬菜");
}
public static void main(String[] args) {
IEat e = new IEat() {
@Override
public void eat(String v) {
System.out.println("正在吃"+v);
}
};
personEat(e);
}
}
interface IEat
{
void eat(String v);
}
改为Lambda实现
public class test {
//此方法调用了IEat接口中的eat方法
public static void personEat(IEat e)
{
e.eat("蔬菜");
}
public static void main(String[] args) {
IEat e = (String v) -> {System.out.println("正在吃" + v);};
personEat(e);
}
}
interface IEat
{
void eat(String v);
}
IEat e = new IEat() {
@Override
public void eat(String v) {
System.out.println("正在吃"+v);
}
};
直接换成了一行
IEat e = (String v) -> {System.out.println("正在吃" + v);};
至此,还可以用Lambda的简化,写为
IEat e = v -> System.out.println("正在吃" + v);
最后,还可以将
IEat e = (String v) -> {System.out.println("正在吃" + v);};
personEat(e);
合并为一行
personEat(v -> System.out.println("正在吃" + v));
最终代码
public class test {
//此方法调用了IEat接口中的eat方法
public static void personEat(IEat e)
{
e.eat("蔬菜");
}
public static void main(String[] args) {
personEat(v -> System.out.println("正在吃" + v));
}
}
interface IEat
{
void eat(String v);
}
最终下来,我终于看懂了这么一行代码,本质就是实现了接口方法的一个对象,这简化的太多了、、、小白阅读起来真是一头雾水
IEat e = v -> System.out.println("正在吃" + v);
这么简单的一行,既定义了一个IEat的对象e
,也实现了接口IEat的方法
实现和定义对象同时进行