一、基础定义
1. 内部类:完整定义在另一个类体内部的类,外层包裹的类称为外部类。
// 外部类
class OuterDemo{
// 内部类
class InnerDemo{}
}
2. 编译产物:内部类编译后单独生成class文件,命名规则:外部类名$内部类名.class。
3. 核心特性:内部类可直接访问外部类所有成员,包含私有属性、私有方法,不破坏外部类封装特性。
4. 四大分类:成员内部类、静态内部类、方法局部内部类、匿名内部类。
二、四类内部类详解
1. 成员内部类(对应外部实例成员)
(1) 定义位置:外部类大括号内、所有方法体之外。
(2) 对象创建规则:必须先创建外部类实例,依托外部对象才能创建内部类对象。
// 第一步创建外部类对象
OuterDemo out = new OuterDemo();
// 依托外部对象创建成员内部类对象
OuterDemo.InnerDemo in = out.new InnerDemo();
(3) 访问外部类当前对象:语法 外部类名.this
• 外部类名.this.成员变量:读取外部类实例属性
• 外部类名.this.成员方法(实参):调用外部类实例方法
(4) 语法限制:成员内部类不允许定义静态变量、静态方法。
2. 静态内部类(对应外部静态成员)
(1) 定义位置:外部类内部、方法体外,使用static关键字修饰。
(2) 成员权限:内部既可以定义实例变量、实例方法,也能定义静态变量、静态方法。
(3) 对象创建规则:无需外部类实例,仅通过外部类类名即可创建。
OuterDemo.StaticInner inner = new OuterDemo.StaticInner();
(4) 静态成员访问:直接用外部类名.静态内部类名访问
• 读取静态属性:OuterDemo.StaticInner.静态变量名
• 调用静态方法:OuterDemo.StaticInner.静态方法(实参)
(5) 访问限制:静态内部类仅能访问外部类静态属性、静态方法,无法访问外部实例成员。
3. 局部内部类(对应方法局部变量)
(1) 定义位置:完整写在某个方法的方法体内部。
(2) 对象创建规则:只能在定义该类的方法内部创建对象,且创建代码必须写在局部内部类定义代码之后。
(3) 访问局部变量规则:局部内部类的方法中若要访问所在方法的局部变量,该变量必须是常量。
补充说明:JDK8及更高版本提供语法糖,若局部变量仅赋值一次、没有二次修改,编译器会自动为变量添加final修饰,无需手动书写。
4. 匿名内部类(特殊的局部内部类,无类名)
(1) 使用前提:必须实现某个接口,或者继承一个普通父类。
(2) 核心特点:一段代码只能创建唯一一个匿名内部类对象,类定义与对象实例化代码合并书写,没有类名。
(3) 标准语法(实现接口场景)
接口类型 变量名 = new 接口名(){
// 重写接口全部抽象方法
@Override
public void 抽象方法名(){
方法业务逻辑;
}
};
(4) 优缺点总结
• 优势:代码简洁紧凑,无需单独新建实现类文件,业务逻辑连贯。
• 劣势:无独立类名,代码可读性较差,复杂逻辑不推荐使用。
案例1:实现接口的匿名内部类
interface InterFaceTest{
void show();
}
public class TestMain{
public static void main(String[] args) {
InterFaceTest test = new InterFaceTest(){
@Override
public void show() {
System.out.println("匿名内部类实现接口重写方法");
}
};
}
}
案例2:继承父类的匿名内部类
public class TestMain{
public static void main(String[] args) {
Parent p = new Parent(){
@Override
public void func() {
System.out.println("匿名子类重写父类func方法");
}
};
p.func();
}
}
class Parent{
public void func(){
System.out.println("原始父类func方法");
}
}