内部类
- 内部类的分类:
① 定义在外部类局部位置上(一般在方法中) 1)局部内部类(有类名) 2)匿名内部类(无类名) ② 定义在外部类的成员位置上 1)成员内部类(无static 修饰) 2) 静态内部类(用static 修饰)
局部内部类
基础认识
class A {
void func() {
class 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
- 匿名内部类只能使用一次
|