系列文章目录
文章目录
- 系列文章目录
- 一、认识内部类
- 1、什么是内部类?
- 2、为什么要学习内部类?
- 二、内部类分类:
- 三、成员内部类
- 1、书写位置
- 2、如何创建成员内部类的对象
- 3、成员内部类如何获取外部类的成员变量
- 四、静态内部类(实则为成员内部类的一种)
- 1、创建静态内部类对象的格式
- 2、调用非静态方法的格式
- 3、调用静态方法的格式
- 4、注意事项
- 五、局部内部类
- 六、匿名内部类
- 1、匿名内部类(的对象)格式的理解
- 2、匿名内部类的使用
- 接口多态
- 直接链式调用方法
- 3、位置
- 七、
- 1、
- 2、
- 3、
- 八、
- 1、
- 2、
- 3、
一、认识内部类
1、什么是内部类?
它是类的五大成员(属性、方法、构造方法、代码块、内部类)之一。
在一个类的里面,再定义一个类。举例:在A类的内部定义B类,B类就被称为内部类,如下图所示,Inner类就是内部类,Outer类就是外部类,他俩之外的其他类,统称为外部其他类。
2、为什么要学习内部类?
二、内部类分类:
成员内部类
静态内部类
局部内部类
匿名内部类
前面三种我们几乎不会自己去写,一般在看源代码的时候才会看到,了解一下,以后源码碰到能看懂即可。
三、成员内部类
1、书写位置
成员内部类写在成员位置的,属于外部类的成员。
成员内部类可以被一些修饰符所修饰,比如:private,默认,protected,public,static(被static修饰的成员内部类变为静态内部类)等
在成员内部类里面,JDK16之前不能定义静态变量,JDK16开始才可以定义静态变量。
2、如何创建成员内部类的对象
方式一:在外部类中编写方法,对外提供内部类的对象。
方式二:直接创建格式:外部类名.内部类名 对象名=外部类对象.内部类对象;
范例:Outer.Inner oi =new Outer().new Inner();
3、成员内部类如何获取外部类的成员变量
内部类对象在堆中开辟的空间中保存了一个指向其外部类的地址,如下图所示。在输出Outer.this.a的时候会先找到Outer后面的this,其存的是001,再去地址为001的空间中找到a。
四、静态内部类(实则为成员内部类的一种)
静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的需要创建对象。
1、创建静态内部类对象的格式
外部类名.内部类名 对象名 = new 外部类名.内部类名(); 比起非静态简单一点。
2、调用非静态方法的格式
先创建对象,用对象调用
3、调用静态方法的格式
外部类名.内部类名.方法名();
4、注意事项
(1)静态内部类也是成员内部类中的一种。
(2)静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的需要创建外部类的对象。
五、局部内部类
1.将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量。
2.外界是无法直接使用局部内部类,需要在方法内部创建对象并使用。
3.该类可以直接访问外部类的成员,也可以访问方法内的局部变量。
六、匿名内部类
1、匿名内部类(的对象)格式的理解
匿名内部类顾名思义是一个没有名字的内部类,“没有名字”是针对我们程序员来说的,编译之后的字节码文件会由JDK给他自动编码上名字。如下图所示,Test$1.class就是Test.java的第一个匿名内部类,而Test$2.class是第二个匿名内部类。
为什么说是匿名内部类的对象呢,是因为用了new这个关键字,而new后面的类名或者接口名可以表明这个匿名内部类是继承了某个类或者实现了某个接口,后面大括号中的内容是类的内容,而这个类并没有名字,且最前面使用了new,所以说这是个对象。
2、匿名内部类的使用
使用场景:当方法的参数是接口或者类时以接口为例,匿名内部类可以传递这个接口的实现类对象。如果实现类只要使用一次,就可以用匿名内部类简化代码。
如果我想调用public static void method(Animal a){a.eat();}
,之前的方法我们需要使用多态,首先定义一个子类来继承Animal,再创建子类的对象作为参数,对method进行调用。现在我们只需如下图所示:传递的参数是一个匿名内部类,调用method方法时相当于Animal a = 子类对象
即使用了多态。此时也需要满足编译看左边,运行看右边。
接口多态
直接链式调用方法
3、位置
可以写在成员位置,即成员匿名内部类(成员内部类的一种),也可以写在局部位置,即局部匿名内部类(局部内部类的一种)。