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的方法
实现和定义对象同时进行

posted @ 2023-11-08 13:51  ecnu_lxz  阅读(14)  评论(0编辑  收藏  举报