一、内部类的定义:定义在类中的类
二、内部类的作用
-
内部类可以访问外部类的所有数据,包括被【private修饰的私有数据】
(1) 为什么内部类可以访问外部类的所有成员变量
内部类编译后会单独生成一份class文件,编译器会自动为内部类添加一个【外部类类型】的实例,内部类通过【外部类名.this】表示这个外部类的当前实例,实现访问外部类的所有成员变量
同时,编译器会自动为内部类的构造方法添加一个外部类类型的参数,在调用内部类的构造方法时会默认传入这个外部类的引用,故,实例化一个Inner Class也不能脱离Outer实例
(2) 外部类访问内部类的成员属性,需要先创建内部类的对象 -
可以对同一个包下的其他类隐藏
(1) 如何实现对外隐藏
内部类可以使用private、protected修饰,当我们用private修饰时,这个内部类就对外隐藏了
(2) 使用场景:当内部类实现某个接口时,在进行向上转型,可完全隐藏接口的实现 -
解决java单继承的缺点
-
想定义一个回调函数(函数又被称为方法),但又不想写大量代码时
通过【匿名内部类】实现
三、内部类的分类 -
非静态内部类
(1) 非静态内部类的创建:【依赖外部类实例的创建】,首先需要创建一个外部类的实例,然后,通过外部类实例来new内部类的实例
创建方式1:
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
创建方式2:
Outer.Inner inner = new Outer().new Inner();
(2) 可以定义非静态变量与静态变量(Java16为了在内部类中声明Record,所以放开了静态变量的限制)
不建议定义静态变量、静态方法的原因:加载外部类时,不会加载非静态内部类,但静态变量、静态方法是随着类的加载开始在内存中创建的,矛盾点:【类还不存在,却希望操作它的变量与方法】
(3) 只可以定义非静态方法
(4) 可以访问外部类的静态变量、非静态变量、静态方法、非静态方法 -
静态内部类
(1) 静态内部类的创建:【不依赖外部类实例的创建】
Outer.StaticNested staticNested = new Outer.StaticNested();
(2) 可以定义非静态变量与静态变量
(3) 只可以定义非静态方法
(4) 可以访问外部类的静态变量、静态方法 -
匿名内部类
-
没有任何修饰符
-
匿名内部类没有类型,故也没有构造方法
-
必须继承一个抽象类或实现一个接口
-
无法定义静态变量、静态方法
-
局部内部类
-
只在一个方法内定义的类,被称为【局部内部类】,作用域:仅限于该方法
-
不允许使用任何修饰符
-
对外完全隐藏,只有创建这个类的方法可以访问