内部类主要有以下几类:成员内部类、局部内部类、静态内部类、匿名内部类
1.成员内部类
成员内部类也称常规内部类,是指内部类直接嵌套在外部类的类体里
这时内部类就相当于外部类的一个成员变量或成员方法,是外部类的一个成员。
在成员内部类中,可以拥有自己的成员变量和方法,也可以是一个独立的类,内部类和外部类
的实例变量是可以共存的。
创建的时候先要创建外部类然后再创建内部类。
1 /*
2 * 成员内部类
3 */
4 public class OuterClass {
5 // 外部类名
6 private String outerClassName = "outerClass";
7 // 内部外部标志 与内部类的对象命名相同
8 private String inOutFlg = "outer";
9
10 public OuterClass(){
11 System.out.println("外部类OuterClass创建完成!");
12 }
13
14 /*
15 * 成员内部类
16 */
17 public class InnerClass {
18 // 内部类名
19 String innerClassName = "InnerClass";
20 // 内部外部标志 与外部类的对象命名相同
21 String inOutFlg = "inner";
22
23 /*
24 * 内部类构造方法
25 */
26 public InnerClass(){
27 System.out.println("内部类InnerClass创建完成!");
28 }
29
30 /*
31 * 打印外部类名
32 */
33 public void printOuterClassValue() {
34 // 在成员内部类中可以访问外部类的所有成员
35 System.out.println(outerClassName);
36 // 当内部类中存在与外部成员变量相同的变量时,外部成员的调用
37 System.out.println(OuterClass.this.inOutFlg);
38 }
39 /*
40 * 打印内部类名
41 */
42 public void printInnerClassValue(){
43 System.out.println(innerClassName);
44 // 当内部类中存在与外部成员变量相同的变量时,内部成员的调用
45 System.out.println(InnerClass.this.inOutFlg);
46 }
47 }
48
49 /*
50 * 外部类内部对内部类的访问
51 */
52 void getClassName (){
53 InnerClass innerClass = new InnerClass();
54 innerClass.printOuterClassValue();
55 }
56
57 }
2 * 成员内部类
3 */
4 public class OuterClass {
5 // 外部类名
6 private String outerClassName = "outerClass";
7 // 内部外部标志 与内部类的对象命名相同
8 private String inOutFlg = "outer";
9
10 public OuterClass(){
11 System.out.println("外部类OuterClass创建完成!");
12 }
13
14 /*
15 * 成员内部类
16 */
17 public class InnerClass {
18 // 内部类名
19 String innerClassName = "InnerClass";
20 // 内部外部标志 与外部类的对象命名相同
21 String inOutFlg = "inner";
22
23 /*
24 * 内部类构造方法
25 */
26 public InnerClass(){
27 System.out.println("内部类InnerClass创建完成!");
28 }
29
30 /*
31 * 打印外部类名
32 */
33 public void printOuterClassValue() {
34 // 在成员内部类中可以访问外部类的所有成员
35 System.out.println(outerClassName);
36 // 当内部类中存在与外部成员变量相同的变量时,外部成员的调用
37 System.out.println(OuterClass.this.inOutFlg);
38 }
39 /*
40 * 打印内部类名
41 */
42 public void printInnerClassValue(){
43 System.out.println(innerClassName);
44 // 当内部类中存在与外部成员变量相同的变量时,内部成员的调用
45 System.out.println(InnerClass.this.inOutFlg);
46 }
47 }
48
49 /*
50 * 外部类内部对内部类的访问
51 */
52 void getClassName (){
53 InnerClass innerClass = new InnerClass();
54 innerClass.printOuterClassValue();
55 }
56
57 }
测试:
1 public static void main(String[] args) {
2 // 外部类的创建
3 OuterClass out = new OuterClass();
4 // 从外部类访问内部类的成员函数
5 out.getClassName();
6 // 内部类的创建
7 OuterClass.InnerClass innerClass = out.new InnerClass();
8 // 访问内部类的成员函数
9 innerClass.printInnerClassValue();
10 }
11
12 }
2 // 外部类的创建
3 OuterClass out = new OuterClass();
4 // 从外部类访问内部类的成员函数
5 out.getClassName();
6 // 内部类的创建
7 OuterClass.InnerClass innerClass = out.new InnerClass();
8 // 访问内部类的成员函数
9 innerClass.printInnerClassValue();
10 }
11
12 }
2.局部内部类
局部内部类也称方法内部类,它对外面的所有类来说都是隐藏的,即使是它所属的外部类,仅有它所在的方法知道它;
它不仅可以访问它所属外部类中的数据,还可以访问该方法中定义的局部变量,不过局部变量必须声明为final类型。
接口声明:
1 public interface InnerClassIF {
2 // 打印内部类名
3 void printInnerClassValue();
4 // 打印外部类名
5 void printOuterClassValue();
6 // 打印方法内定义的变量
7 void printOuterMethodValue();
8 }
2 // 打印内部类名
3 void printInnerClassValue();
4 // 打印外部类名
5 void printOuterClassValue();
6 // 打印方法内定义的变量
7 void printOuterMethodValue();
8 }
1 /*
2 * 方法内部类
3 */
4 public class OuterClass {
5 // 外部类名
6 private String outerClassName = "outerClass";
7 // 内部外部标志 与内部类的对象命名相同
8 private String inOutFlg = "outer";
9
10 public OuterClass(){
11 System.out.println("外部类OuterClass创建完成!");
12 }
13
14 /*
15 * 方法内部定义的类,只能在该方法范围内访问
16 */
17 InnerClassIF getClassName (){
18 String path = "D盘";
19 final String classPath = "C盘";
20
21 /*
22 * 方法内部类
23 */
24 class InnerClass implements InnerClassIF {
25 // 内部类名
26 String innerClassName = "InnerClass";
27 // 内部外部标志 与外部类的对象命名相同
28 String inOutFlg = "inner";
29
30 /*
31 * 内部类构造方法
32 */
33 public InnerClass(){
34 System.out.println("内部类InnerClass创建完成!");
35 }
36
37 /*
38 * 打印外部类名
39 */
40 public void printOuterClassValue() {
41 // 在方法内部类中可以访问外部类的所有成员
42 System.out.println(outerClassName);
43 // 当内部类中存在与外部成员变量相同的变量时,外部成员的调用
44 System.out.println(OuterClass.this.inOutFlg);
45 }
46 /*
47 * 打印内部类名
48 */
49 public void printInnerClassValue(){
50 System.out.println(innerClassName);
51 // 当内部类中存在与外部成员变量相同的变量时,内部成员的调用
52 System.out.println(InnerClass.this.inOutFlg);
53 }
54 /*
55 * 打印方法内定义的变量
56 */
57 public void printOuterMethodValue(){
58 // 在方法内部类中只能访问该方法中用final定义的成员
59 System.out.println(classPath);
60 }
61 };
62 return new InnerClass();
63 }
64
65 }
2 * 方法内部类
3 */
4 public class OuterClass {
5 // 外部类名
6 private String outerClassName = "outerClass";
7 // 内部外部标志 与内部类的对象命名相同
8 private String inOutFlg = "outer";
9
10 public OuterClass(){
11 System.out.println("外部类OuterClass创建完成!");
12 }
13
14 /*
15 * 方法内部定义的类,只能在该方法范围内访问
16 */
17 InnerClassIF getClassName (){
18 String path = "D盘";
19 final String classPath = "C盘";
20
21 /*
22 * 方法内部类
23 */
24 class InnerClass implements InnerClassIF {
25 // 内部类名
26 String innerClassName = "InnerClass";
27 // 内部外部标志 与外部类的对象命名相同
28 String inOutFlg = "inner";
29
30 /*
31 * 内部类构造方法
32 */
33 public InnerClass(){
34 System.out.println("内部类InnerClass创建完成!");
35 }
36
37 /*
38 * 打印外部类名
39 */
40 public void printOuterClassValue() {
41 // 在方法内部类中可以访问外部类的所有成员
42 System.out.println(outerClassName);
43 // 当内部类中存在与外部成员变量相同的变量时,外部成员的调用
44 System.out.println(OuterClass.this.inOutFlg);
45 }
46 /*
47 * 打印内部类名
48 */
49 public void printInnerClassValue(){
50 System.out.println(innerClassName);
51 // 当内部类中存在与外部成员变量相同的变量时,内部成员的调用
52 System.out.println(InnerClass.this.inOutFlg);
53 }
54 /*
55 * 打印方法内定义的变量
56 */
57 public void printOuterMethodValue(){
58 // 在方法内部类中只能访问该方法中用final定义的成员
59 System.out.println(classPath);
60 }
61 };
62 return new InnerClass();
63 }
64
65 }
测试:
1 public static void main(String[] args) {
2 // 外部类的创建
3 OuterClass out = new OuterClass();
4 // 访问成员方法,返回内部类对象的引用
5 InnerClassIF innerClassIF = out.getClassName();
6 innerClassIF.printInnerClassValue();
7 innerClassIF.printOuterClassValue();
8 innerClassIF.printOuterMethodValue();
9
10 }
2 // 外部类的创建
3 OuterClass out = new OuterClass();
4 // 访问成员方法,返回内部类对象的引用
5 InnerClassIF innerClassIF = out.getClassName();
6 innerClassIF.printInnerClassValue();
7 innerClassIF.printOuterClassValue();
8 innerClassIF.printOuterMethodValue();
9
10 }
3.静态内部类
在一个内部类前添加修饰符static,这个内部类就变为静态内部类。在一个静态内部类中可以声明静态成员和非静态成员,但是在非静态内部类中
不可以声明静态成员。同样,在静态内部类中不能访问外部类的非静态成员。
静态内部类的对象可以直接生成,不需要外部类的对象来生成,可以把静态内部类看作是一个顶级类。
静态内部类不可以用private来修饰。
1 /*
2 * 静态内部类
3 */
4 public class OuterClass {
5 // 外部类名
6 private static String outerClassName = "outerClass";
7 // 内部外部标志 与内部类的对象命名相同
8 private static String inOutFlg = "outer";
9
10 public OuterClass(){
11 System.out.println("外部类OuterClass创建完成!");
12 }
13
14 /*
15 * 静态内部类
16 */
17 public static class InnerClass {
18 // 内部类名
19 static String innerClassName = "InnerClass";
20 // 内部外部标志 与外部类的对象命名相同
21 String inOutFlg = "inner";
22
23 /*
24 * 内部类构造方法
25 */
26 public InnerClass(){
27 System.out.println("内部类InnerClass创建完成!");
28 }
29
30 /*
31 * 打印外部类名
32 */
33 public static void printOuterClassValue() {
34 // 在静态内部类中可以访问外部类的所有静态成员
35 System.out.println(outerClassName);
36 // 当内部类中存在与外部成员变量相同的变量时,外部成员的调用
37 System.out.println(OuterClass.inOutFlg);
38 }
39 /*
40 * 打印内部类名
41 */
42 public void printInnerClassValue(){
43 System.out.println(innerClassName);
44 // 当内部类中存在与外部成员变量相同的变量时,内部成员的调用
45 System.out.println(InnerClass.this.inOutFlg);
46 }
47 }
48 }
2 * 静态内部类
3 */
4 public class OuterClass {
5 // 外部类名
6 private static String outerClassName = "outerClass";
7 // 内部外部标志 与内部类的对象命名相同
8 private static String inOutFlg = "outer";
9
10 public OuterClass(){
11 System.out.println("外部类OuterClass创建完成!");
12 }
13
14 /*
15 * 静态内部类
16 */
17 public static class InnerClass {
18 // 内部类名
19 static String innerClassName = "InnerClass";
20 // 内部外部标志 与外部类的对象命名相同
21 String inOutFlg = "inner";
22
23 /*
24 * 内部类构造方法
25 */
26 public InnerClass(){
27 System.out.println("内部类InnerClass创建完成!");
28 }
29
30 /*
31 * 打印外部类名
32 */
33 public static void printOuterClassValue() {
34 // 在静态内部类中可以访问外部类的所有静态成员
35 System.out.println(outerClassName);
36 // 当内部类中存在与外部成员变量相同的变量时,外部成员的调用
37 System.out.println(OuterClass.inOutFlg);
38 }
39 /*
40 * 打印内部类名
41 */
42 public void printInnerClassValue(){
43 System.out.println(innerClassName);
44 // 当内部类中存在与外部成员变量相同的变量时,内部成员的调用
45 System.out.println(InnerClass.this.inOutFlg);
46 }
47 }
48 }
测试:
1 public static void main(String[] args) {
2 // 外部类直接访问静态内部类的静态方法
3 OuterClass.InnerClass.printOuterClassValue();
4 // 访问静态内部类的非静态方法
5 OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
6 innerClass.printInnerClassValue();
7 }
2 // 外部类直接访问静态内部类的静态方法
3 OuterClass.InnerClass.printOuterClassValue();
4 // 访问静态内部类的非静态方法
5 OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
6 innerClass.printInnerClassValue();
7 }
4.匿名内部类
匿名内部类是唯一一种没有构造方法的类。大部分匿名内部类用于接口的回调。
1 public class InnerClassTest {
2 public static void main(String[] args) {
3 ArrayList<Integer> valueList = new ArrayList<>();
4
5 valueList.add(26);
6 valueList.add(2);
7 valueList.add(5);
8 valueList.add(4);
9 valueList.add(19);
10 valueList.add(15);
11 valueList.add(1);
12 valueList.add(3);
13 valueList.add(6);
14 valueList.add(30);
15
16 // 匿名内部类用于继承其他类或实现接口,只是对继承方法的实现与重写,不需要添加额外的方法
17 Collections.sort(valueList, new Comparator<Integer>() {
18
19 @Override
20 public int compare(Integer o1, Integer o2) {
21 // 升序
22 if (o1.intValue() < o2.intValue()) {
23 return -1;
24 }
25 return 0;
26 }
27 });
28
29 for (int i = 0; i < valueList.size(); i++) {
30 System.out.println(valueList.get(i));
31 }
32 }
33 }
2 public static void main(String[] args) {
3 ArrayList<Integer> valueList = new ArrayList<>();
4
5 valueList.add(26);
6 valueList.add(2);
7 valueList.add(5);
8 valueList.add(4);
9 valueList.add(19);
10 valueList.add(15);
11 valueList.add(1);
12 valueList.add(3);
13 valueList.add(6);
14 valueList.add(30);
15
16 // 匿名内部类用于继承其他类或实现接口,只是对继承方法的实现与重写,不需要添加额外的方法
17 Collections.sort(valueList, new Comparator<Integer>() {
18
19 @Override
20 public int compare(Integer o1, Integer o2) {
21 // 升序
22 if (o1.intValue() < o2.intValue()) {
23 return -1;
24 }
25 return 0;
26 }
27 });
28
29 for (int i = 0; i < valueList.size(); i++) {
30 System.out.println(valueList.get(i));
31 }
32 }
33 }