内部类

内部类

如果一个类的定义被包含在另一个类内部,则该类称为==内部类==。

带有static修饰的内部类,称为==静态内部类==。不带有static修饰的被称为==实例内部类==。

如果内部类的定义被包含在一个方法内部,则称为==局部内部类==。

成员内部类的主要特点:

  1. 内部类可以定义为private的,那么其它类看不到该类;
  2. 内部类中的方法不但可以访问自己内部的域,还可以访问外围类中的所有域、包括私有域;

局部内部类对象不但可访问外围类对象中的成员,还可访问方法的局部变量。

内部类虽然定义在外围类中,但在运行时,==java虚拟机将它和普通类同样看待==。==内部类对象==和==外围类对象==是==各自独立==的,并==没有包含关系==。

内部类分类

  • 成员内部类

    1. static成员内部类
    2. 非static成员内部类
  • 局部内部类

    匿名内部类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class OutClass02{


//静态成员内部类
static class Dog{

}

//非静态成员内部类
class Bird{

}


//成员方法
public void method(){
//局部内部类
class aa{

}
}

//代码块
{
//局部内部类
class BB{

}
}

//构造方法
public OutClass02(){
//局部内部类
class CC{

}
}
}

成员内部类:

  • 一方面,作为外部类的成员

    》可以==调用外部类结构==

    》可以==被 static 修饰== (外部类不能被 static 修饰,但是作为内部类可以被 static 修饰)

    》可以被四种不同的权限修饰

  • 另一方面,作为一个类

    》定义属性、方法、构造器

    》可以被==final==修饰,表示此类不能被继承。言外之意,不使用==final==表示可以被继承

    》可以被==abstract==修饰,表示不能被实例化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
class OutClass02{

//外部类属性
String name;
int age;
//外部类成员方法
public void eat(){
System.out.println("人吃饭");
}

//静态成员内部类
static class Dog{
//静态成员内部类属性
String name;
int age;

//静态成员内部类方法
public void show(){
System.out.println("这是真的狗!!");
//静态内部类不能调用非静态成员
// eat();
}


}

//非静态成员内部类
final class Bird{
//内部类属性
String name;

//内部类构造器
public Bird(){

}

//内部类方法
public void sing(){
System.out.println("我是一个歌手!!!");

//可以非静态内部类可以调用外部类非静态成员
eat();
OutClass02.this.eat(); //调用外部类的方法
}
}


//成员方法
public void method(){
//局部内部类
class aa{

}
}

//代码块
{
//局部内部类
class BB{

}
}

//构造方法
public OutClass02(){
//局部内部类
class CC{

}
}
}

关注如下三个问题

如何实例化成员内部类的对象

1
2
3
4
5
6
7
8
9
//创建Dog对象(静态成员内部类)
OutClass02.Dog dog = new OutClass02.Dog();
//使用静态成员内部类对象调用静态成员内部类方法
dog.show();

//创建Bird对象(非静态成员内部类)
OutClass02.Bird bird = new OutClass02().new Bird();
//使用非静态成员内部类对象调用非静态成员内部类结构
bird.sing();

如何在成员内部类中区分调用外部类结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class OutClass02{

//外部类属性
String name = "小明";
int age;

//内部类
final class Bird{
//内部类属性
String name = "叽叽";

//内部类构造器
public Bird(){

}

//内部类方法
public void sing(){
System.out.println("我是一个歌手!!!");

//可以非静态内部类可以调用外部类非静态成员
eat();
OutClass02.this.eat(); //调用外部类的方法
}

//区分调用外部类结构
public void disPlay(String name){
//访问形参name变量
System.out.println(name);
//访问内部类name变量
System.out.println(this.name);
//访问外部类name变量
System.out.println(OutClass02.this.name);
}
}
}

开发中局部内部类的使用

1、内部类==不能被public、private、static修饰==;

2、在==外部类中不能创建内部类的实例==;

3、==创建内部类的实例只能在包含他的方法中==;

4、==内部类访问包含他的方法中的变量必须有final修饰==;

5、==外部类不能访问局部内部类==,==只能在方法体中访问局部内部类==,且访问必须在内部类定义之后。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class InnerClassDemo03 {

//开发中很少见
public void method(){
class AA{

}
}

//返回一个实现了Comparable接口的对象
public Comparable getComparable(){

//局部内部类
//创建一个实现了Comparable接口的类
//方式一:
class MyComparable implements Comparable{
@Override
public int compareTo(Object o) {
return 0;
}
}

return new MyComparable();

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class InnerClassDemo03 {

//开发中很少见
public void method(){
class AA{

}
}

//返回一个实现了Comparable接口的对象
public Comparable getComparable(){

//局部内部类
//方式二:
//创建一个实现Comparable接口的匿名内部类
return new Comparable(){

@Override
public int compareTo(Object o) {
return 0;
}
};
}
}