匿名内部类和Lambda表达式

匿名内部类

定义: 匿名内部类是没有名称的内部类
说明: 在调用包含有接口类型参数的方法时,通常为了简化代码,可以直接通过匿名内部类的形式传入一个接口类型参数,在匿名内部类中直接完成方法的实现。

/*
*匿名内部类的前提
*必须是类或者接口
*
*格式:
*
*new 类名/接口名(){
*重写抽象方法
*}
*/
public class Demo01 {
	public static void main(String[] args) {
		//整体等效于:是Animal父类的子类对象
		//new Animal(){
		//  @Ovrride
		//  public void eat() {
		//     System.out.println("我吃饭");
		//  }
		//};
		
		//方法一
	    new Animal(){
		  @Ovrride
		  public void eat() {
		    System.out.println("我吃饭");
		 }
		}.eat();

        //方法二
        //通过匿名内部类访问局部变量.在JDK版本之前,必须加final关键字
        String name = "路西法";
        
        Animal a = new Animal(){
		  @Ovrride
		  public void eat() {
		    System.out.println(name+"在吃饭");
		 }
		};
		a.eat();
	}
}
public abstract class Animal {
	public abstract void eat();
}
public class Dog extends Animal{
	@Ovrride
	public void eat() {
		System.out.println("狗吃肉");
	}
}
public class Demo02 {
	public static void main(String[] args) {
	  function(
	   	new Inner() {
		  @Ovrride
		  public void method() {
		    Sysytem.out.println("我重写后的menthod方法");
		    }
		}.method();
	   );
	}

    public static void function(Inter i) {
        i.method();
    }
}
public interface Inter {
	public abstract void method();
}

Lambda表达式

Lambda表达式介绍
Java8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁。通过Lambda表达式,可以替代我们以前经常写的匿名内部类来实现接口。Lambda表达式本质是一个匿名函数


Lambda表达式语法
(int a,int b) -> (return a+b);
本质是一个函数;

一般的函数类似如下:

int add(int a,int b) {
	return a+b;
}

有返回值,方法名,参数列表,方法体

Lambda表达式函数的话,只有参数列表方法体
(参数列表) -> {方法体}
说明:
(): 用来描述参数列表
{}: 用来描述方法体
->: Lambda运算符,可以叫做箭头符号,或者goes to

案例;接口方法参数,无参,单个参数,两个参数,有返回值,没有返回值,这六种情况都罗列下:

public class Program {
	public static void main(String[] args) {
		If1 if1 = ()->{
			System.out.println("无参数无返回值");
		};
		if1.test();

        If2 if2 = (int a)->{
        	System.out.println("单个参数无返回值 a="+a);
        if2.test(3);

        If3 if3 = (int a,int b)->{
        	System.out.println("两个参数无返回值 a+b"+(a+b));
        };
        if3.test(1,5);

        If4 if4 = ()->{
        	return 4;
        };
        System.out.println("无参数有返回值"+if4.test();

        If5 if5 = (int a)->{
        	return a;
        };
        System.out.println("单个参数有返回值"+if5.test(5));

        If6 if6 = (int a,int b)->{
        	return a-b;
        };
        System.out.println("多个参数有返回值"+if6.test(7,1));
	}
	
 
    interface If1{
    	/**
    	*无参数无返回值
    	*/
    	void test();
    }

    interface If2{
    	/**
    	*单个参数无返回值
    	*/
    	void test(int a);
    }
    
    interface If3{
    	/**
    	*两个参数无返回值
    	*/
    	void test(int a,int b);
    }

    interface If4{
    	/**
    	*无参数有返回值
    	*/
    	int test();
    }

	interface If5{
		/**
		*单个参数有返回值
		*/
		int test(int a);
	}

	interface If6{
	    /**
		*多个参数有返回值
		*/
		int test(int a,int b);
	}
}

Lambda表达式精简语法
1.参数类型可以省略
2.假如只有一个参数,()括号可以省略
3.如果方法体只有一条语句,{}大括号可以省略
4.如果方法体中唯一的语句是return返回语句,那省略大括号的同时return也要省略

public class Program2 {
	public static void main(String[] args) {
		If1 if1 = ()->System.out.println("无参数无返回值");
		if1.test();

        If2 if2 = a->System.out.println("单个参数无返回值 a="+a);
        if2.test(3);

        If3 if3 = (a,b)->System.out.println("两个参数无返回值 a+b"+(a+b));
        if3.test(1,5);

        If4 if4 = ()-> 4;
        System.out.println("无参数有返回值"+if4.test();

        If5 if5 = a->a;
        System.out.println("单个参数有返回值"+if5.test(5));

        If6 if6 = (a,b)->a-b;
        System.out.println("多个参数有返回值"+if6.test(7,1));
	}
	
 
    interface If1{
    	/**
    	*无参数无返回值
    	*/
    	void test();
    }

    interface If2{
    	/**
    	*单个参数无返回值
    	*/
    	void test(int a);
    }
    
    interface If3{
    	/**
    	*两个参数无返回值
    	*/
    	void test(int a,int b);
    }

    interface If4{
    	/**
    	*无参数有返回值
    	*/
    	int test();
    }

	interface If5{
		/**
		*单个参数有返回值
		*/
		int test(int a);
	}

	interface If6{
	    /**
		*多个参数有返回值
		*/
		int test(int a,int b);
	}
}

**方法引用** 有时候多个lambda表达式实现函数是一样的话,我们可以封装成通用方法,以便于维护,这时候可以用方法引用实现: 语法是:对象::方法 假如是static方法,可以直接 类名::方法 实例如下:
public class Program3 {
	public static void main(String[] args) {
        //If5 if5 = a->a-2;
        //System.out.println(if5.test(3));

        //If5 if52 = a->a-2;
        //System.out.println(if5.test(5));

		Program3 program3 = new Program3();
		If5 if5 = program3::testA;
		System.out.println(if5.test(3));

		If5 if52 = program3::testA;
		System.out.println(if52.test(5));

		If5 if53 = Program3::testB;
		If5 if54 = Program3::testB;
		System.out.println(if53.test(3));
		System.out.println(if54.test(3));
	}
	
	public int testA(int a) {
		return a-2;
	}

	public static int testB(int a) {
		return a-2;
	}
	
	interface If5{
		/**
		*单个参数有返回值
		*/
		int test(int a);
	}
}

构造方法引用
如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用;
语法:类名::new
实例:
先定义一个Dog实体,实现无参和有参构造方法;

public class Dog {
	private String name;
	private int age;
	
	public Dog() {
		System.out.println("无参构造方法");
	}

	public Dog(String name,int age) {
		System.out.println("有参构造方法");
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void getAge(int age) {
		this.age = age;
	}

    @Ovrride
    public String toString() {
    	return "Dog(" +
    			"name+'" + name + '\' +
    			", age=" + age +
    			")";
    }
}

public class Program4 {
	public static void main(String[] args) {
		/*DogService dogService=()->{
			return new Dog();
		};
		System.out.println(dogService.getGog());*/

        /*DogService dogService=()->new Dog();
		System.out.println(dogService.getGog());*/

		DogService dogService=Dog::new;
		System.out.println(dogService.getGog());

		DogService dogService2=Dog::new;
		System.out.println(dogService2.getDog("向玉明",24))
	}

	interface DogService{
		Dog getDog();
	}

	interface DogService2{
		Dog getDog(String name,int age);
	}
}

@FunctionallInterface注解
这个注解是函数式接口注解,所谓的函数式接口,首先的一个接口,然后这个接口里面只能有一个抽象方法
这种类型的接口也成为SAM接口,即Single Abstract Method interfaces

特点

  • 接口有且仅有一个抽象方法
  • 允许定义静态方法
  • 允许定义默认方法
  • 允许java.lang.Object中的public方法
  • 该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错
//正确的函数式接口
@FunctionalInterface
public interface TestInterface {
	//抽象方法
	public void sub();

	//java.lang.Object中的public方法
	public boolean equals(Object var1);

	//默认方法
	public default void defaultMethod(){
	}

	//静态方法
	public static void staticMethod(){
	}
}

//错误的函数式接口(有多个抽象方法)
@FunctionalInterface
public interface TetInterface2 {
	void add();
	void sub();
}

你可能感兴趣的:(java,jvm,开发语言)