2022-07-28 学习笔记 day21-JavaSE-内部类与Lambda表达式

内部类与Lambda表达式

内部类

什么是内部类

  一般来说,类与类之间的独立的,使用内部类能打破这种独立,让一个类成为内一个类的成员,与成员变量和成员方法同级。

为什么要使用内部类

  采用内部类这种技术,可以隐藏内部的结构和细节,封装性更好。

内部类经过编译也会生成字节码文件,具体格式是这样的"OuterClass$InnerClass.class"

实例内部类

  1. 实例内部类必须用外部类实例来创建,和成员变量的使用方法是一致的
  2. 定义位置:类体中

在外部类的外部创建内部类对象

在这里插入图片描述
在外部类的内部创建内部类对象

在这里插入图片描述

静态内部类

  1. 静态内部类可以不通过外部类实例来创建,可以直接创建静态内部类实例
  2. 定义位置:类体中

局部内部类

  1. 定义位置:定义在方法的方法体中,注意:由于方法体中的代码是有执行顺序的,所以对局部内部类的声明最好写到方法体的开头位置
  2. 作用域:方法体中,从声明位置开始,到“}”结束

匿名内部类

1.没有名字的接口实现类

匿名内部类的使用

import java.util.Arrays;
import java.util.Date;
public class Test2 {

	//使用匿名内部类给实例变量赋值
	public A a = new A(){
		public void method() {
			System.out.println("method");
		}
	};

	public static void main(String[] args) throws Exception{
		//使用匿名内部类调用内部方法
		new Test() {
			public void test() {
				System.out.println("test");
			}
		}.test();

		//使用匿名内部类作为方法参数传入
		method(new Test(){
			public void test() {
				System.out.println("test");
			}
		});
	}


	public static void method(Test test) {
		test.test();
	}

	
}

interface A {
	void method();
}

interface Test {
	void test();
}

四种内部类使用案例

public class Test1 {
	public static void main(String[] args){
		//调用实例内部类
		new OuterClass().new InnerClass();

		//调用静态内部类
		OuterClass.StaticInnerClass.display();

		//匿名内部类
		new OuterClass().interface1.interMethod();
	}
}


class OuterClass {
	
	//Constructor
	public OuterClass() {
		System.out.println("OuterClass Constructor");
	}
	//1.实例内部类
	class InnerClass {
		public InnerClass() {
			System.out.println("OuterClass InnerClass Constructor");
		}
	}

	//内部类实例方法
	public void outerClassMethod (){
		System.out.println("OuterClass OuterClassMethod");
		//2.局部内部类
		class LocalInnerClass {
			void display() {
				System.out.println("OuterClass OuterClassMethod LocalInnerClass");
			}
		}
		//调用局部内部类的方法
		new LocalInnerClass().display();
	}

	//3.静态内部类
	public static class StaticInnerClass {
		static void display() {
			System.out.println("OuterClass StaticInnerClass");
		}
	}
	
	//4.匿名内部类
	public Interface1 interface1 = new Interface1() {
		public void interMethod() {
			System.out.println("OuterClass Interface1 interMethod");
		}
	};

	
}
interface Interface1 {
	void interMethod();
}


四种内部类编译后生成的字节码文件

在这里插入图片描述

Lambda表达式(箭头函数)与函数式接口

函数式接口

如果一个接口只有一个抽象方法,我们还可以将这个接口称作函数式接口,可以用注解@FunctionalInterface标识

Lambda表达式(箭头函数)Java8新特性

  1. 箭头函数要求必须用函数式接口接收(只有函数式接口才能使用箭头函数)
  2. 语法格式:(param1,param2) -> {方法体};
  3. 省略规则:
    1. 只有一个参数时,可以省略“()”
    2. 无返回值且方法体中只有一条java语句时,可以省略“{}”

Lambda使用代码

public class Test4 {

	//有参数有返回值
	Sum sum = (a,b) -> {return a+b;};

	//有参数无返回值
	Print print = (a) -> {
		System.out.println("result2: " + a);
	};

	//无参数有返回值
	Test1 test1 = () -> {return 3;};

	//无参数无返回值
	Test2 test2 = () -> {System.out.println("result4");};public static void main(String[] args){
		Test4 test = new Test4();
		//1
		int result1 = test.sum.sum(1,2);
		System.out.println("result1: " + result1);
		//2
		test.print.print(1);
		//3
		int result3 = test.test1.test();
		System.out.println("result3: " + result3);
		//4
		test.test2.test();

	}
}

//有参有返回值
@FunctionalInterface
interface Sum {
	int sum(int a,int b);
}

//有参无返回值
@FunctionalInterface
interface Print {
	void print(int a);
}

//无参有返回值
@FunctionalInterface
interface Test1 {
	int test();
}
//无参无返回值
@FunctionalInterface
interface Test2 {
	void test();
}

匿名内部类与Lambda表达式的区别

所需类型不同
  1.匿名内部类:可以是接口,抽象类,具体类
  2.Lambda表达式:只能是接口
使用限制不同
  1.如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
  2. 如果接口中多于一个抽象方法,就只能使用匿名内部类,而不能使用Lambda表达式
实现原理不同:
  1.匿名内部类:编译之后,产生一个单独的.class字节码文件
  2.Lambda表达式:编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值