一、嵌套类嵌套类存在的作用或者目的:(1)使多继承的解决方案变得完整 (2)将存在一定逻辑关系的类组织在一起,又对外隐藏。定义(嵌套类的表现方式为):嵌套类是定义在另一个类、接口、方法或代码块里的类。分类:内部类(非静态嵌套类) 静态嵌套类1.1 内部类定义:内部类是定义在另一个类、接口、方法或代码块里,没有Static修饰的嵌套类分类:成员内部类、局部内部类、匿名内部类特点:是独立的类,编译成独立的.class文件不能含有静态变量、静态代码块、静态方法(静态常量除外,拥有外部类所有元素的访问权限)作用:(1)很好的实现了隐藏,使多继承的解决 (2)方案得以完整,解决父类和接口同名方法问题1.1.1 成员内部类定义:成员内部类是定义在另一个类或接口里的内部类应用:1.成员内部类的声明// Outer.java - 外部类 package com.bwie.member; public class Outer { // Outer类的成员 // 成员内部类(不能与外部类重名) // 可以使用final、访问修饰符修饰 public final class Inner { // Inner类的成员 private String message; public Inner() { this.message = "成员内部类实例"; } public void display() { System.out.println(message); } } // 外部类成员方法 public void outerMethod() { System.out.println("外部类方法"); } }// Test.java - 在其他类中创建成员内部类的实例 package com.bwie.member; // 导入成员内部类 import com.bwie.member.Outer.Inner; public class Test { public static void main(String[] args) { // 必须先创建外部类对象才能创建成员内部类对象 Outer outer = new Outer(); // 通过外部类对象创建内部类对象 Inner inner = outer.new Inner(); inner.display(); // 也可以直接使用完整路径(不导入) Outer.Inner inner2 = outer.new Inner(); inner2.display(); } }关键点说明:成员内部类定义在外部类的成员位置,是一个独立的类,编译后会生成Outer$Inner.class文件不能与外部类重名可以使用final、访问修饰符(public、protected、private、default)修饰创建成员内部类对象必须先有外部类对象:outer.new Inner()导入时使用import com.bwie.member.Outer.Inner;(见示例)2.成员内部类中可以声明的内容// Outer.java - 外部类 package com.bwie.member; public class Outer { // Outer类的成员变量、成员方法、构造方法等 // 外部类的静态成员(静态成员的加载早于成员内部类) public static String field1 = "外部类静态变量"; public static void method1() { System.out.println("外部类静态方法"); } // 外部类的实例成员 private String outerField = "外部类实例变量"; public Outer() { System.out.println("外部类构造方法"); } public void outerMethod() { System.out.println("外部类实例方法"); } // ========== 成员内部类 ========== public class Inner { // 1. 实例变量 private String field; // 2. 构造方法 public Inner() { this.field = "成员内部类默认字段"; } public Inner(String field) { this.field = field; } // 3. 实例方法 public void method() { System.out.println("成员内部类实例方法: " + field); } // 可以访问外部类的成员(包括私有成员) public void accessOuter() { System.out.println("访问外部类实例变量: " + outerField); System.out.println("访问外部类静态变量: " + Outer.field1); Outer.method1(); outerMethod(); } // 4. 静态常量(允许,因为常量在编译阶段会进行替换) public static final String FIELD1 = "静态常量(编译时替换)"; // 注意:不能声明普通的静态变量或静态方法(非final) // public static String staticField; // 编译错误! // public static void staticMethod() {} // 编译错误! } }// Test.java - 测试类 package com.bwie.member; public class Test { public static void main(String[] args) { // 创建外部类对象 Outer outer = new Outer(); // 创建成员内部类对象(必须先有外部类对象) Outer.Inner inner = outer.new Inner(); inner.method(); // 使用带参数的构造方法 Outer.Inner inner2 = outer.new Inner("自定义字段值"); inner2.method(); // 访问外部类成员 inner2.accessOuter(); // 访问内部类的静态常量(编译时替换,可直接通过类名访问) System.out.println("内部类静态常量: " + Outer.Inner.FIELD1); } }关键点总结:可以声明的内容示例✅ 实例变量private String field;✅ 构造方法public Inner() {}✅ 实例方法public void method() {}✅ 静态常量(final)public static final String FIELD1 = "..."❌ 普通静态变量/方法编译错误(静态成员加载早于成员内部类)特别注意:public static final常量可以在成员内部类中声明,因为它在编译阶段会被替换为字面量值,不依赖类加载普通的静态成员(非final)不允许在成员内部类中声明成员内部类可以访问外部类的所有成员(包括私有成员)3.成员内部类如何访问外部成员// Outer.java - 外部类 package com.bwie.member; public class Outer { // 外部类实例变量 private String str1 = "Outer类的str1"; private String str = "Outer类的str"; // 外部类实例方法 public void print() { System.out.println("Outer类的print方法"); } // ========== 成员内部类 ========== public class Inner { // 内部类自己的同名实例变量(演示内部类成员优先于外部类成员) private String str = "Inner类的str"; public void visitOuter() { // 1. 直接访问外部类成员(外部类成员与内部类成员不同名时) System.out.println(str1); // 直接访问外部类成员 print(); // 直接访问外部类方法 // 2. 内部类成员优先于外部类成员(同名时) System.out.println(str); // 优先访问内部类自己的str // 如果想要访问外部类的同名成员,需要使用 Outer.this System.out.println(Outer.this.str); // 访问外部类的str } } }// Test.java - 测试类 package com.bwie.member; public class Test { public static void main(String[] args) { // 创建外部类对象 Outer outer = new Outer(); // 创建内部类对象并调用方法 outer.new Inner().visitOuter(); // 分步写法 // Outer.Inner inner = outer.new Inner(); // inner.visitOuter(); } } //运行结果 Outer类的str1 Outer类的print方法 Inner类的str Outer类的str关键点总结:场景访问方式示例内部类中访问外部类成员(不同名)直接访问str1、print()内部类中访问外部类成员(同名)使用外部类名.this.成员Outer.this.str内部类中访问自己的成员直接访问str核心规则:直接访问:当内部类成员与外部类成员不同名时,可以直接使用成员名访问外部类成员内部类优先:当内部类成员与外部类成员同名时,内部类自己的成员优先指定外部类成员:使用Outer.this.成员名来明确访问外部类的同名成员成员内部类可以访问外部类的所有成员(包括private修饰的私有成员)3.1 如何在成员内部类中访问外部类中同名的成员// Outer.java - 外部类 package com.bwie.member; public class Outer { // 外部类实例变量 private String str = "Outer类的str"; private String str1 = "Outer类的str1"; // 外部类实例方法 public void print() { System.out.println("Outer类的print方法"); } // ========== 成员内部类 ========== public class Inner { // 内部类自己的同名实例变量(与外部类str同名,用于演示访问区分) private String str = "Inner类的str"; // 内部类私有成员(用于演示外部类通过内部类对象访问私有成员) private String str1 = "Inner类的私有str1"; private static final String str2 = "Inner类的静态常量str2"; // 内部类实例方法 private void print() { System.out.println("Inner类的私有print方法"); } /** * 方式一:在成员内部类中访问外部类成员 * 使用 "外部类名.this.成员" 访问外部类的同名成员 */ public void visitOuter() { // 1. 直接访问内部类自己的成员(优先) System.out.println("内部类自己的str: " + str); // 2. 访问外部类的成员(与内部类不同名时,直接访问) System.out.println("外部类的str1: " + str1); // 注意:这里的str1与内部类同名,实际访问的是内部类的str1 // 上面的写法访问的是内部类的str1(因为内部类成员优先),正确访问外部类str1应使用下方写法 // 3. 使用 "外部类名.this.成员" 访问外部类的同名成员 System.out.println("外部类的str(通过Outer.this.str): " + Outer.this.str); System.out.println("外部类的str1(通过Outer.this.str1): " + Outer.this.str1); // 4. 直接调用外部类方法(不同名时直接调用) print(); // 注意:这里调用的是内部类自己的print方法(因为内部类有同名方法) // 5. 使用 "外部类名.this.成员" 调用外部类的同名方法 Outer.this.print(); // 明确调用外部类的print方法 } } /** * 方式二:在外部类中通过成员内部类对象访问内部类成员 * 可以通过内部类对象访问内部类的所有成员(包括私有成员) */ public void visitInner() { // 创建内部类对象 Inner inner = new Inner(); // 1. 通过内部类对象访问内部类的私有实例变量 System.out.println("访问内部类私有实例变量str1: " + inner.str1); // 2. 通过内部类类名访问内部类的静态常量(私有static final也可以访问) System.out.println("访问内部类私有静态常量str2: " + Inner.str2); // 3. 通过内部类对象调用内部类的私有实例方法 inner.print(); } }// Test.java - 测试类 package com.bwie.member; public class Test { public static void main(String[] args) { // 创建外部类对象 Outer outer = new Outer(); System.out.println("========== 内部类访问外部类成员 =========="); // 创建内部类对象并调用visitOuter方法 Outer.Inner inner = outer.new Inner(); inner.visitOuter(); System.out.println("\n========== 外部类访问内部类私有成员 =========="); // 外部类方法访问内部类私有成员 outer.visitInner(); } } //运行结果 ========== 内部类访问外部类成员 ========== 内部类自己的str: Inner类的str 外部类的str1: Inner类的私有str1 外部类的str(通过Outer.this.str): Outer类的str 外部类的str1(通过Outer.this.str1): Outer类的str1 Inner类的私有print方法 Outer类的print方法 ========== 外部类访问内部类私有成员 ========== 访问内部类私有实例变量str1: Inner类的私有str1 访问内部类私有静态常量str2: Inner类的静态常量str2 Inner类的私有print方法关键点总结场景访问方式说明内部类中访问外部类同名成员Outer.this.成员外部类名.this 表示外部类的当前对象内部类中访问外部类不同名成员直接使用成员名如str1、print()内部类中访问自身成员直接使用成员名内部类自己的成员优先于外部类外部类中访问内部类私有实例成员内部类对象.成员外部类可以访问内部类的私有成员外部类中访问内部类私有静态常量内部类名.成员外部类可以访问内部类的私有静态常量核心规则:使用外部类名.this.成员可以在内部类中明确访问外部类的同名成员外部类可以访问内部类的所有成员(包括private修饰的私有成员),因为内部类是外部类的成员当内部类成员与外部类成员同名时,内部类成员优先4.成员内部类的使用注意事项:1.1.2 局部内部类定义:定义在方法或代码块里的内部类应用:1.使用局部内部类// Outer.java - 外部类 package com.bwie.local; public class Outer { // 外部类成员变量 private String outerField = "外部类成员变量"; // ========== 静态代码块中的局部内部类 ========== static { // 局部内部类 Inner1 定义在静态代码块中 // 只能在使用之前定义 class Inner1 { private String message = "静态代码块中的局部内部类"; public void display() { System.out.println(message); // 静态代码块中的局部内部类只能访问外部类的静态成员 System.out.println("访问外部类静态变量: " + Outer.staticField); } } // 只能在定义它的代码块中使用 Inner1 inner1 = new Inner1(); inner1.display(); } // 外部类静态变量(供静态代码块中的局部内部类访问) private static String staticField = "外部类静态变量"; // ========== 实例方法中的局部内部类 ========== public void method() { // 方法中的局部变量 String localVar = "方法中的局部变量"; // 局部内部类 Inner2 定义在方法中 // 只能在使用之前定义 // 可以使用 abstract 或 final 修饰 final class Inner2 { private String message = "实例方法中的局部内部类"; public void display() { System.out.println(message); // 可以访问外部类的成员变量 System.out.println("访问外部类成员变量: " + outerField); // 可以访问方法中的局部变量(必须是 final 或 effectively final) System.out.println("访问方法局部变量: " + localVar); } } // 只能在定义它的方法中使用 Inner2 inner2 = new Inner2(); inner2.display(); } // ========== 另一个重载方法(演示不同方法中可以有同名局部内部类) ========== public void method(String param) { // 不同方法中可以定义同名的局部内部类 // 编译成不同的 .class 文件:Outer$1Inner2.class 和 Outer$2Inner2.class class Inner2 { private String message = "另一个方法中的局部内部类(同名)"; public void display() { System.out.println(message + ", 参数: " + param); } } Inner2 inner2 = new Inner2(); inner2.display(); } // ========== 代码块中的局部内部类 ========== public void testBlock() { int condition = 1; if (condition 0) { // 局部内部类 Inner3 定义在 if 代码块中 // 只能在定义它的代码块中使用 class Inner3 { private String message = "if代码块中的局部内部类"; public void display() { System.out.println(message); } } Inner3 inner3 = new Inner3(); inner3.display(); } // 下面这行编译错误:Inner3 只能在定义它的 if 代码块中使用 // Inner3 inner3 = new Inner3(); // 编译错误! } // ========== 局部内部类不能与外部类重名 ========== public void testNameConflict() { // 下面这行编译错误:局部内部类不能与外部类重名 // class Outer { } // 编译错误! // 可以定义其他名称 class LocalClass { public void display() { System.out.println("合法的局部内部类名称"); } } } }// Test.java - 测试类 package com.bwie.local; public class Test { public static void main(String[] args) { // 创建外部类对象 Outer outer = new Outer(); System.out.println("\n========== 调用方法中的局部内部类 =========="); outer.method(); System.out.println("\n========== 调用另一个重载方法 =========="); outer.method("测试参数"); System.out.println("\n========== 测试代码块中的局部内部类 =========="); outer.testBlock(); } } //运行结果 静态代码块中的局部内部类 访问外部类静态变量: 外部类静态变量 ========== 调用方法中的局部内部类 ========== 实例方法中的局部内部类 访问外部类成员变量: 外部类成员变量 访问方法局部变量: 方法中的局部变量 ========== 调用另一个重载方法 ========== 另一个方法中的局部内部类(同名), 参数: 测试参数 ========== 测试代码块中的局部内部类 ========== if代码块中的局部内部类关键点总结特性说明示例定义位置定义在方法或代码块({})中static{}、method()、if{}编译结果独立的.class文件,命名如Outer$1Inner.class前面冠以外部类名和$符号使用范围只能在定义它的方法或代码块中使用超出定义范围无法访问定义时机只能在使用之前定义先定义后使用修饰符限制只能使用abstract或final不能使用public、private、static等名称限制不能与外部类重名class Outer在局部内部类中非法特殊规则:局部内部类可以访问外部类的所有成员(包括私有成员)局部内部类访问方法中的局部变量时,该变量必须是final或effectively final(实际上未被修改)不同方法或代码块中可以定义同名的局部内部类,编译后会生成不同的.class文件静态代码块中的局部内部类只能访问外部类的静态成员2.局部内部类中可以声明的内容// Outer.java - 外部类 package com.bwie.local; public class Outer { // ========== 外部类的成员 ========== // 外部类成员变量 private String outerField = "外部类实例变量"; // 外部类构造方法 public Outer() { System.out.println("外部类构造方法"); } // 外部类实例方法 public void outerMethod() { System.out.println("外部类实例方法"); } // 外部类静态变量(静态成员的加载早于局部内部类) public static String field1 = "外部类静态变量"; // 外部类静态方法 public static void method1() { System.out.println("外部类静态方法"); } // ========== 静态代码块 ========== static { // 静态代码块在类加载时执行,早于局部内部类的定义 System.out.println("外部类静态代码块执行"); } // ========== 实例方法中的局部内部类 ========== public void method() { // 方法中的局部变量 String localVar = "方法中的局部变量"; // ======================================== // 局部内部类 Inner // 可以声明的内容: // 1. 实例变量 ✅ // 2. 构造方法 ✅ // 3. 实例方法 ✅ // 4. 静态常量(public static final)✅(常量在编译阶段进行替换) // 5. 普通静态变量 ❌(编译错误) // 6. 普通静态方法 ❌(编译错误) // ======================================== class Inner { // 1. 实例变量 ✅ private String field; private int count; // 2. 构造方法 ✅ public Inner() { this.field = "局部内部类默认字段"; this.count = 0; } public Inner(String field, int count) { this.field = field; this.count = count; } // 3. 实例方法 ✅ public void method() { System.out.println("局部内部类实例方法"); System.out.println("field: " + field); System.out.println("count: " + count); } // 可以访问外部类的成员(包括私有成员) public void accessOuterM