内部类
- 内部类的分类:
① 定义在外部类局部位置上(一般在方法中)
1)局部内部类(有类名)
2)匿名内部类(无类名)
② 定义在外部类的成员位置上
1)成员内部类(无static
修饰)
2) 静态内部类(用static
修饰)
局部内部类
基础认识
- 位置:
class A {
//外部类A
void func() {
//局部内部类C
class C {
}
}
}
//其他类C
class B{}
- 本质:
class
类
局部内部类和普通类一样可以有属性、方法、构造器、代码块、内部类
class Outer {
//外部类
void func01() {
//局部内部类
class Inner {
int a;//属性
void func02(){}//方法
Inner(){}//构造器
{}//代码块
}
}
}
- 地位:局部变量
1)不能添加访问修饰符,但是可以用final
2)作用域:只在定义它的方法/代码块中
局部内部类的访问
- 局部内部类 直接访问 外部类的所有成员
- 外部类访问局部内部类 需创建对象再访问
- 外部其他类 不能访问 局部内部类
class Outer {
//外部类
int n=1;
void func01() {
//局部内部类
class Inner {
void func02(){
System.out.println("Inner直接访问Outer中的n:"+n);
}
}
Inner inner = new Inner();
inner.func02();
}
}
重名问题:由于局部内部类可以直接访问到自己类和外部类的所有成员,当外部类成员与自己类成员重名时,会遵循就近原则,若局部内部类想访问外部类成员时用外部类名.this.成员
class Outer {
//外部类
int a=1;
void func01() {
//局部内部类
class Inner {
int a;
void func02(){
System.out.println("局部内部类"+a+" 外部类"+Outer.this.a);
}
}
Inner inner = new Inner();
inner.func02();
}
}
【补充以上原理】:Outer.this
其实就是外部类的对象,即哪个对象调用了func01()
,Outer.this
就是哪个
class Outer {
//外部类
int a=1;
void func01() {
//局部内部类
class Inner {
int a;
void func02(){
System.out.println("局部内部类中的a:"+a+" 外部类中的a:"+Outer.this.a);
System.out.println(Outer.this);
}
}
Inner inner = new Inner();
inner.func02();
}
}
//其他类
class A{}
public class InnerClass {
public static void main(String[] args) {
Outer outer = new Outer();
outer.func01();
System.out.println(outer);
}
}
匿名内部类
语法
new 类或接口(参数列表){
};
本质:无名字的class
类 + 对象
若B类的方法
func01()
想调用接口IA的func02()
,则需要在写一个C类实现IA的func02()
,然后在B类方法func01()
中创建一个对象ia,调用func02()
,但ia只使用了一次这样浪费空间,那么如何合理调用func02()
?这时匿名内部类解决上述问题,简化开发
解决方式如下:
interface IA{
void func02();
}
class B{
void func01(){
IA C=new IA(){
@Override
public void func02() {
System.out.println("this is C");
}
};
C.func02();
System.out.println(C.getClass());
}
}
- C的编译类型为:IA
- C的运行类型为:匿名内部类——>B$1
- 匿名内部类只能使用一次