如果一个事物包含另一个事物,那么这就是一个类内部包含另一个类
例如:人体和心脏,汽车和发动机
分类
- 成员内部类
- 局部内部类(包含匿名内部类)
成员内部类
格式:
1
2
3
4
5
6
|
修饰符 class 外部类名称{
修饰符 class 内部类名称{
//...
}
//...
}
|
注意;内用外,随意访问。外用内,需要内部类对象
1
2
3
4
5
6
7
8
9
10
11
|
public class Body{//外部类
public class Heart{//内部类
public void beat(){//内部类的方法
System.out.println("bibibi");
System.out.println("my name is"+name);
}
}
private String name;
}
|
如何使用成员内部类?
方法:
- 间接方式:在外部类的方法当中,使用内部类;然后main只是调用内部类的方法
- 直接方式:外部类名称 .内部类名称 对象名 = new 外部类名称().new 内部类名称
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public class Body{//外部类
public class Heart{//内部类
public void beat(){//内部类的方法
System.out.println("bibibi");
System.out.println("my name is"+name);
}
}
public void methodBody(){
Heart heart = new Heart();
heart.beat();
//或者
new Heart.beat();
}
private String name;
}
|
1
2
3
4
5
6
7
|
public class Demo{
Body bo = new Body();
//通过外部类对象调用外部类方法,里面间接使用内部类Heart
bo.methodBody();
//直接访问
Body.Heart heart = new Body().new Heart();
}
|
内部类的同名变量访问
外部类名称.this.外部类成员变量名
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class Outer{
int num = 10;
public class Inner{
int num = 20;
public void method(){
int num = 30;
System.out.println(num);//30
System.out.println(this.num);//20
System.out.println(Outer.this.num);//
}
}
}
|
局部内部类
如果一个类定义在方法内部,那么这就是一个局部内部类
“局部”:只有当前所属的方法才能使用它,出了方法外就不能用了
格式:
1
2
3
4
5
6
7
8
|
修饰符 class 外部类名称{
修饰符 返回值类型 外部类方法名称(参数列表){
class 局部类名称{
//...
}
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public class Outer{
public void methodOuter(){
class Inner{//局部内部类
int num = 10;
public void methodInner(){
System.out.println(num);
}
}
Inner inner = new Inner();
inner.methodInner;
}
}
public class Demo{
public static void main(String[] args){
Outer obj = new Outer();
obj.methodOuter();//10
}
}
|
权限修饰符的小结:
public > protected > (default) > private
- 外部类:public,default
- 成员内部类:都行
- 局部内部类:都不行
匿名内部类
如果接口的实现了类(或父类的子类),只需要使用唯一一次
那么该情况下可省略该类的定义,称为匿名内部类
格式:
1
2
3
|
接口名称 对象名 = new 接口名称(){
//覆盖重写抽象方法
};
|
实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public interface MyInterface{
public void method(){
System.out.println("这是接口");
}
}
public class Demo{
public static void main(String[] args){
MyInterface obj = new MyInterface(){
@override
public void method(){
System.out.println("这是匿名内部类");
}
};
obj.method();//这是匿名内部类
}
}
|
对格式"new 接口名称(){…}“解析
- new 代表创建对象动作
- 接口名称就是匿名内部类需要实现哪个接口
- {///…}是匿名内部类内容
另外几点
- 匿名内部类在【创建对象】时,只能使用唯一一次
如果希望多次创建对象。而且类内容一样,需要单独定义实现类
- 匿名对象在调用方法时,只能调用唯一一次
如果希望同一对象,调用多个方法,必须给对象起名字
- 匿名内部类省略了实现类,匿名对象省略了【对象名称】。两个不是一回事
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
|
public interface MyInterface{
public void method(){
System.out.println("这是接口");
}
}
public class Demo{
public static void main(String[] args){
MyInterface obj = new MyInterface(){
@override
public void method(){
System.out.println("这是匿名内部类");
}
};
obj.method();//这是匿名内部类
new MyInterface(){//匿名对象
@override
public void method(){
System.out.println("这是匿名内部类");
}
}.method();
}
}
|