学习记录22内部类
内部类
什么是内部类?
类的五大成员:1.属性;2.方法;3.构造方法;4.代码块;5.内部类
内部类:在一类的里面再定义一个类。在A类里面定义一个B类,B就是内部类,A就是外部类,而与这两个类无关的类,就叫外部其他类;然后在外部其他类当中创建内部类的对象
为什么学习内部类?应用场景是什么?
需求:写一个javabean类描述汽车
属性:汽车品牌、车龄、颜色、发动机品牌、发动机使用年限
我们看的出,发动机是一个独立的个体,但他又是汽车的一部分,如果把发动机单独提取出来形成一个类,没有什么意义,所以我们愿把它作为汽车的内部类
应用场景:
1.内部类表示的事务是外部类的一部分;
2.内部类单独列出来没有任何意义
内部类的访问特点:
1.内部类可以直接访问外部类的成员,包括私有成员
2.外部类不能直接访问内部类,想要访问内部类成员,必须创建对象

内部类怎么使用呢?

粉色m是类中的方法;橙色f是属性;蓝色c是内部类
集合的遍历方式有很多,之前学到的for循环只是很简单的一种,还有一种遍历方式叫Itr,这是一种很好的遍历集合的方法,它相对集合来讲是相对独立,但如果独立出来,没有与集合产生联系的话,又如何发挥作用呢?所以要先有集合,再有Itr,于是就把Itr设定为集合的内部类
- B类表示的事物是A类的一部分,且B单独存在没有意义。比如汽车的发动机、ArrayList的迭代器、人的心脏等等
内部类的分类
- 成员内部类
- 静态内部类
- 局部内部类
前三个主要是在解读源码的时候见到的 - 匿名内部类
经常用到
成员内部类
成员内部类的代码如何书写
- 写在成员位置,属于外部类的成员,如,上面写到的车和发动机
它和外部类成员的地位是相同的,都属于外部类成员
成员内部类可以被一些修饰符所修饰,比如:private(修饰后,不能再外部其他类中创建对象)、默认、protected、public、static等,
而当用static修饰,就不叫成员内部类,叫做静态内部类
JDK16之前不能定义为静态变量,之后就可以定义静态变量
如何创建成员内部类的对象
- 方式一(private修饰内部类时):
在外部类中编写方法,对外提供内部类对象(类似于get/set方法对私有属性的作用)
![]()
注意:内部类的对象的数据类型不能是InterClass.Engine,因为外部是不知道内部类的存在的(因为修饰符是private,或者可以改变修饰符),也就是无法识别,索引当想要用引用来承载内部类实例化时,可以使用多态的形式,默认父类为Object
- 方式二:
直接创建格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象
![]()
成员内部类如何获取外部类的成员变量
面试题:

不能用super调用,因为外、内部类不是父子类关系。两者的字节码文件是相互独立的。
静态内部类
内部类用static关键字修饰,就叫静态内部类
静态内部类只能访问外部类当中的静态属性和方法;如果想要访问外部类当中的非静态成员,必须创建外部类对象
-
创建静态内部类对象格式:
外部类名.内部类名 对象名 = new 外部类.内部类();。由于是静态修饰,所以在创建对象时,就不需要再实例化对象,直接用类名就可以访问 -
调用非静态方法的格式:
先创建对象,用对象调用 -
调用静态方法格式:
外部类名.内部类名.方法名();
(ideaJDK版本低,不能用static修饰成员。这里不做演示。引用b站视频截屏)

静态方法的调用,不提倡用对象调用。通常采用外部类.内部类.方法名()的方式调用
总结:
- 什么是静态内部类?
静态内部类,是。一种特殊的的成员内部类 - 直接创建内部类对象方式:
Outer.Inter oi = new Outer.Inter();用类名调用,而且要记住,这是内部类的对象,不是外部类的,所以new操作符作用的是Inter - 如何调用静态内部类中的方法:
非静态:创建对象之后,用对象调用;
静态:用外部类名.内部类名.方法名()调用
局部内部类
-
将内部类定义在方法里面的就叫做局部类,类似于方法里面的局部变量
public、protected、默认、private,只能用来修饰成员,不能用来修饰局部变量,要搞清楚什么是成员、什么是局部,可以用final修饰
![]()
-
外界是无法直接使用的,需要在方法内部创建对象并使用
外界无法直接使用成员方法中的局部变量的,自然也就无法使用局部内部类
想要访问:在外部类的方法中创建局部内部类的对象
![]()
-
该类可以直接访问外部类的成员,也可以访问方法内的局部变量
![]()
结果:
![]()
匿名内部类
匿名内部类:本质就是隐藏了名字的内部类
格式:
new 类名或者接口名(){
重写方法;//重写接口中所有的抽象方法
}
内部主要的是:继承或实现、方法重写(重写接口中所有的抽象方法)、创建对象
举例:
new Inter(){
@Override
public void show(){
......
}
};
描述:一个类通过implements与接口对接,而当我们把代码块前面的语句删掉,也就是删掉public class Student implements Swim这条语句,这个时候代码块就是一个没有主人、没有名字的代码块,这个时候我们再把他命名为接口;这就相当于,现在这个没有名字的类,想要实现Swim这个接口,于是就把接口名写在代码块前面,里面的重写方法仍然保留,就是重写里面的所有抽象方法
它的本质是接口的实现类
- 如何创建这个匿名内部类的对象?
对比:
普通对象的创建:类名 对象名 = new 类名();
匿名内部类的对象:new 接口名/类名()(这个括号,代表空参创建对象;可以加入形参)
匿名内部类所包含的有三样:
- 1.实现关系
- 2.方法重写
- 3.创建对象
大括号最后那个;号不能丢,这一整个代码,其中“new 接口名/类名()”叫做创建对象,而整个大括号叫做匿名内部类他写在测试类当中,它的本质就是在创建一个匿名对象
上面提到的new后面写接口名,也可以写类名,写类名的情况就是,这个类是个抽象类;这个时候就不叫实现关系了,就叫继承关系,继承关系自然要重写方法
当然也同样包含了三个东西:1.继承关系;2.方法重写;3.创建对象(通过new来实现)

应用场景:
比如,我需要完成某一个行为,这个行为已经被提取到父类当中去了,是抽象父类、抽象行为,根据之前所学:
1.我们要创建一个子类,把这个父类继承,并且重写所有抽象方法;
2.我们需要使用的时候,就在测试类当中创建子类对象,而后调用方法。
但如果我只需要使用一次这个方法名的方法,那么为这一次,单独创建一个类并且在测试类中创建对象等等,就会太麻烦。
这个时候我们就可以考虑使用匿名内部类

结果:

匿名内部类的格式:
new 类/接口名(){
重写方法;
};
代码整体是一个创建对象的过程,打括号内部是一个类,他实现了以三个东西,1.实现/继承关系;2.方法重写;3.创建对象
1.所以说可以用一个接口/类的类型的变量接收这个对象
2.整体是个对象,所以说他可以调用自己类中的所有方法
总结:
- 匿名内部类仅仅只是一个没有名字的内部类,可以写在方法中局部变量位置(匿名局部类),也可以写在方法外成员位置(匿名外部类),
- 格式:(上面写了不再重复)
- 格式细节:包含了继承或实现,方法重写,创建对象。整体就是一个类的子类对象或者接口的实现类对象
- 使用场景:
当方法的参数是接口或者类时;
以接口为例,可以传递这个接口的实现类对象
但如果实现类只需要使用一次,就可以用匿名内部类简化代码,就不需要为此在专门写一个子类







浙公网安备 33010602011771号