内部类主要有以下几类:成员内部类、局部内部类、静态内部类、匿名内部类
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 }
测试:
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.局部内部类
局部内部类也称方法内部类,它对外面的所有类来说都是隐藏的,即使是它所属的外部类,仅有它所在的方法知道它;
它不仅可以访问它所属外部类中的数据,还可以访问该方法中定义的局部变量,不过局部变量必须声明为final类型。
接口声明:
1
public
interface InnerClassIF {
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 }
测试:
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 }
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 }
测试:
1
public
static
void main(String[] args) {
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 }