一、内部类的分类
-
定义在外部类局部位置上(比如方法/代码块内):
(1)局部内部类(有类名)
(2)匿名内部类(没有类名,重点)
-
定义在外部类的成员位置上:
(1)成员内部类(没有static修饰)
(2)静态内部类(使用static修饰)
二、局部内部类的使用
- 可以直接访问外部类的所有成员
- 不能添加访问修饰符,但可以使用final修饰
- 作用域:仅仅在定义它的方法或代码块中
- 局部内部类访问外部类的成员【访问方式:直接访问】
- 外部类访问访问局部内部类的成员【访问方式:创建对象,再访问(注:必须在作用域内)
- 外部其它类不能访问局部内部类
- 当外部内和局部内部类重名时,默认遵循就近原则,如果访问外部类的成员,则可以使用 外部类名.this.成员 去访问
三、匿名内部类的使用
匿名内部类是定义在外部类的局部位置,比如方法中,并且没有类名。本质是类,该类没有名字,同时还是一个对象
- 匿名内部类的基本语法
public class AnonymousLnnearClass {
public static void main(String[] args) {
Outer o = new Outer();
o.f1();
}
}
class Outer{
private int n1=999;
public void f1(){
//创建一个基于类的匿名内部类
Person p = new Person(){
@Override
public void hi() {
System.out.println("匿名内部类重写了hi方法");
}
};
p.hi();//动态绑定
//也可以直接调用
new Person(){
@Override
public void hi() {
System.out.println("匿名内部类重写了hi方法,并直接调用");
}
}.hi();
}
}
class Person{
public void hi(){
System.out.println("Person hi()");
}
}
- 匿名内部类本身是一个对象,它既定义了类的特征,也有创建对象的特征。
- 可以直接访问外部类的所有成员,包括私有的
- 不能添加访问修饰符,因为它的地位就是一个局部变量
- 作用域:仅仅在定义它的方法或代码块中
- 匿名内部类访问外部类成员【访问方式:直接访问】
- 外部其它类不能访问匿名内部类
- 如果外部和内部类的成员重名时,默认遵循就近原则,如果访问外部类的成员,则可以使用 外部类名.this.成员 去访问
- 匿名内部类可直接作为方法的参数
public class InnerClassExercise {
public static void main(String[] args) {
CellPhone cellPhone = new CellPhone();
Bell ring1 = new Bell() {
@Override
public void ring() {
System.out.println("起床了");
}
};
cellPhone.alarmClock(ring1);
//将匿名内部类作为方法参数
cellPhone.alarmClock(new Bell() {
@Override
public void ring() {
System.out.println("起床了起床了");
}
});
}
}
interface Bell{
void ring();
}
class CellPhone{
public void alarmClock(Bell bell){
bell.ring();
}
}
四、成员内部类
成员内部类是定义在外部类的成员位置,并且没有static修饰
-
可以直接访问外部类的所有成员
-
可以添加任意访问修饰符
-
作用域:整个类体
-
成员内部类访问外部类【访问方式:直接访问】
-
外部类访问成员内部类【访问方式:创建对象再访问】
-
外部其它类访问成员内部类
-
如果外部和内部类的成员重名时,默认遵循就近原则,如果访问外部类的成员,则可以使用 外部类名.this.成员 去访问
五、静态内部类
静态内部类是定义在外部类的成员位置,并且有static修饰
-
可以直接访问外部类的所有静态成员,但不能访问非静态成员
-
可以添加任意访问修饰符
-
作用域:整个类体
-
静态内部类访问外部类【访问方式:直接访问所有静态成员】
-
外部类访问静态内部类【访问方式:创建对象再访问】
-
外部其它类访问静态内部类(new 类名A.类名B)
-
如果外部和内部类的成员重名时,默认遵循就近原则,如果访问外部类的成员,则可以使用 外部类名.this.成员 去访问