[TOC]
>[success] # 内部类
当**一个类的定义**出现在**另外一个类的类体**中时,那么这个类叫做**内部类(Inner)**,而这个内部类**所在的类**叫做**外部类(Outer)**
**内部类**和其他类中可声明使用的内容都一样,只是作为一种`类形式的成员变量`,类中的内容(**成员变量、成员方法、构造方法、静态成员、构造块和静态代码块、内部类**)
>[info] ## 内部类作用
**当一个类**存在的价值**仅仅是为某一个类单独服务**时,那么就可以将这个类定义为所服务类中的内部类,这样可以**隐藏该类的实现细节**并且可以方便的访问外部类的私有成员而**不再需要提供公有的get和set方法**
>[info] ## 内部类种类
1. **普通内部类** \- 直接将一个类的定义放在另外一个类的类体中。
2. **静态内部类** \- 使用static关键字修饰的内部类,隶属于类层级。
3. **局部内部类** \- 直接将一个类的定义放在方法体的内部时。
4. **匿名内部类** \- 就是指没有名字的内部类
>[warning] ### 普通(成员)内部类
* 写法格式
~~~
`访问修饰符` class `外部类的类名` {
`访问修饰符` class `内部类的类名` {
内部类的类体;
}
}
~~~
* 调用内部类
1. 如果**内部类是public 修饰的成员** 先创建外部类
2. 声明的内部类类型 **`外部类.内部类` 变量名 = `外部类声明对象.new` `内部类()`**
例如下面案例
~~~
// 创建外部类
Outer outer = new Outer();
// 执行内部类
Outer.Inner inner = outer.new Inner();
// 调用 内部类show 方法
inner.show();
~~~
>[danger] ##### 代码
~~~
package task10;
/**
* 实现普通内部类
* */
public class Outer {
public int num = 1;
// 定义内部类
public class Inner{
// 定义内部变量
public int innerNum = 10;
// 内部类构造方法
public Inner(){
System.out.println("执行内部构造方法");
}
public void show(){
// 打印外部变量
System.out.println("外部num变量:"+num); // 1
System.out.println("内部变量innerNum:" + innerNum); // 10
}
}
}
~~~
* 调用
~~~
public class ExecuteOuter {
// 执行入口
public static void main(String[] args){
// 创建外部类
Outer outer = new Outer();
// 执行内部类
Outer.Inner inner = outer.new Inner();
// 调用 内部类show 方法
inner.show();
}
}
~~~
>[danger] ##### 使用特点
1. 普通内部类和普通类一样可以定义**成员变量、成员方法以及构造方法等**
2. 普通内部类和普通类一样可以使用**final或者abstract关键字修饰**也可以使用**private或protected**关键字进行修饰。
~~~
/*private*/public /*final*/ class Inner{ }
~~~
3. 普通内部类需要使用**外部类对象来创建对象**。
~~~
// 创建外部类
Outer outer = new Outer();
// 执行内部类
Outer.Inner inner = outer.new Inner();
// 调用 内部类show 方法
inner.show();
~~~
4. 如果内部类访问外部类中与本类内部同名的成员变量或方法时,需要使用**this关键字**。作用域就近原则,此时最近的是函数的形参,在其次this表示当前内部类,想用外部类需要 `外部类.this.变量` 调用
~~~
/**
* 实现普通内部类
* */
public class Outer {
public int num = 1;
// 定义内部类
/*private*/public /*final*/ class Inner{
// 定义内部变量
public int innerNum = 10;
public int num = 2;
// 内部类构造方法
public Inner(){
System.out.println("执行内部构造方法");
}
public void show(int num){
// 打印外部变量
System.out.println("此时接受是调用传进来的num:"+num); // 此时接受是调用传进来的num
System.out.println("内部类中num:" + this.num); // 2
System.out.println("外部类中的num:" + Outer.this.num); // 1
}
}
}
~~~
**注**:简单说(他就是一个写在类里的类,用法特性和类都一样)。
>[warning] ### 静态内部类
* 写法格式
~~~
`访问修饰符` class `外部类的类名` {
` 访问修饰符 static` class `内部类的类名` {
内部类的类体;
}
}
~~~
* 调用静态内部类
~~~
外部类.内部类 对象名 = new 外部类.内部类();
~~~
>[danger] ##### 使用特点
1. 静态内部类不能直接访问外部类的非静态成员。
2. 静态内部类在使用时候可以直接创建对象。例如:
OuterStatic.InnerStatic innerStatic = new OuterStatic.InnerStatic();
3. 如果静态内部类访问外部类中与本类内同名的成员变量或方法时,需要**使用类名.的方式访问**。
>[danger] ##### 代码
~~~
public class OuterStatic {
public int a = 1;
public static int b = 2;
public int c = 999;
public static int d = 1000;
// 创建静态内部类
public static class InnerStatic {
// 内部类属性
public int a = 3;
public static int b = 4;
public void show() {
// System.out.println(c); // error: 静态内部不能直接外部类的非静态成员
System.out.println(d); // 访问外部类静态属性 1000
System.out.println(a + "----" + b); // 就近原则访问内部 3----4
// 如果静态内部类访问外部类中与本类内同名的成员变量或方法时,需要使用类名.的方式访问
System.out.println(OuterStatic.b); // 2
}
}
}
~~~
* 调用
~~~
public class TestOuterStatic {
public static void main(String[] args) {
OuterStatic.InnerStatic innerStatic = new OuterStatic.InnerStatic();
innerStatic.show();
}
}
~~~
>[warning] ### 局部内部类
* 注:局部内部类与局部变量一样,不能使用访问控制修饰符(public、private 和 protected)和 static 修饰符修饰。
~~~
访问修饰符 class 外部类的类名 {
访问修饰符 返回值类型 成员方法名(形参列表) {
(这里没有修饰符)class 内部类的类名 {
内部类的类体;
}
}
}
~~~
* 使用局部内部类只在当前方法中有效
>[danger] ##### 特点
1. 局部内部类只能在该方法的内部可以使用。
2. 局部内部类可以在方法体内部直接创建对象。
3. 局部内部类不能使用访问控制符和static关键字修饰符。
4. 局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内部类和局部变量的声明周期不同所致。如下图虽然局部变量在局部类中使用时候会默认加上final,但如果赋值此时不符合final 定义变量,局部类中会报错
![](https://img.kancloud.cn/4d/53/4d530b95d053cb4b1c79ef91b4b30933_764x358.png)
5. 如果方法中的成员与外部类中的成员同名,则可以使用 .this. 的形式访问外部类中的成员。
>[danger] ##### 案例
~~~
import java.security.PublicKey;
public class FunInner {
// 外部类变量
int a = 1;
int b = 2;
public void show() {
// 局部变量
int d = 3; // 如果局部 内部局部类使用该属性默认会加上final 即final int d = 3,如果只局部类使用最好加final 修饰
// 定义局部内部类,局部内部类不能使用访问控制符和static关键字修饰符
class FInner {
// static int b = 2; // 内部不能不能定义 static 成员
int a = 11;
int c = 4;
public void show() {
System.out.println(a + "---" + b + "----" + c); // 就近原则 11---2----4
System.out.println(FunInner.this.a); // 访问外部同名 1
System.out.println(d); // 访问局部 3
// d = 36; // error在局部内部类中只可以访问当前方法中 final 类型的参数与变量,final 变量不能重新赋值
}
}
FInner fInner = new FInner();
fInner.show();
}
public static void main(String[] args) {
FunInner funInner = new FunInner();
funInner.show();
}
}
~~~
- windows -- 环境变量
- Vscode -- 编写java
- 初始java
- java -- 关键字
- 编写第一个java程序
- java -- 注释
- 计算机存储 -- 进制
- java -- 类型
- java -- 变量
- 数字类型
- 布尔类型
- 字符类型
- 类型转换
- 双等比较是什么
- java -- 运算符
- 算数运算符
- 字符串拼接
- 关系/比较运算符
- 自增减运算符
- 逻辑运算符
- 三目运算
- 赋值运算符
- 移位运算符
- 位运算符
- 运算符优先级
- java -- 流程控制语句
- if /else if /if -- 判断
- switch case分支结构
- for -- 循环
- 用双重for循环
- while -- 循环
- do while -- 循环
- 案例练习
- java -- 数组
- 数组的存储
- 数组的增删改查
- 数组的特点
- 数组案例
- 二维数组
- 数组的工具方法
- java -- 方法
- java -- 方法的重载
- java -- 方法的调用流程
- java -- 类方法传参注意事项
- java -- 方法练习案例
- 对比 return break continue
- for each循环
- java -- 基础练习
- java -- 面向对象
- java -- 创建类和对象
- java -- 访问控制符
- java -- 类成员方法
- java -- 构造方法
- java -- this
- java -- 封装
- java -- 对象内存图
- java -- 创建对象案例
- java -- static
- java -- 继承
- super -- 关键字
- java -- 构造块和静态代码块
- java -- 重写
- java -- final
- java -- 多态
- java -- 抽象类
- java -- 接口
- 引用类型数据转换
- 综合案例
- java -- 内部类
- java -- 回调模式
- java -- 枚举类型
- java -- switch 使用枚举
- java -- 枚举方法使用
- java -- 枚举类实现接口
- java -- javaBean
- java -- package 包
- java -- import
- java -- 递归练习
- java -- 设计模式
- 单例模式
- java -- 注解
- java -- 元注解
- Java -- 核心类库
- java -- 处理字符串
- Java -- String
- String -- 常用方法
- String -- 正则
- Java -- StringBuilder 和 StringBuffer
- 知识点
- Java -- StringJoiner 字符串拼接
- 练习题
- 字符串的总结
- Java -- 包装类
- Integer
- Double
- Boolean
- Character
- java -- 集合类
- java -- util.Collection
- Iterator接口
- java -- util.List
- java -- ArrayList
- java -- util.Queue
- java -- util.Set
- java -- util.Map
- java -- util.Collections
- Java -- Math
- Java -- java.lang
- Java -- Object
- Java -- 获取当前时间戳
- Java -- 异常
- Java -- java.util
- java -- Date
- java -- Calender
- Java -- java.text
- Java -- SimpleDateFormat
- Java -- java.time
- Java -- java.io
- java -- io.File
- java -- 泛型
- IDEA -- 用法