内部类
一、 定义:在一个类内部定义的类。
二、 类型:成员内部类、局部内部类(也叫方法内部类)、匿名内部类、静态嵌套类。
三、 用法
a) 四种内部类的共性
i. 内部类仍然是一个独立的类,在编译后内部类会被编译成独立的.class文件,只是在前面加上外部类的类名和$符号。
ii. 内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由访问外部类的成员变量,无论是否是private的。
iii. 内部类的this引用:内部类中同样使用this.成员变量,如要使用外部类的成员变量,则使用外部类名.this.成员变量。
b) 四种内部类的区别
i. 成员内部类:它相当于外部类的一个成员变量或方法,可用修饰符为final、abstract、public、private、protected、strictfp和static。形式如下
class Outer {
class Inner{}
}
编译上述代码会产生两个文件,Outer.class和Outer$Inner.class。成员内部类内不允许有任何静态声明!能够访问成员内部类的途径是通过外部类的对象或外部类中非静态的方法。
//外部类
class Outer {
//内部类
class Inner {
//内部类的方法
public void myInner() {
System.out.println(“Inner class”);
}
}
//非静态方法访问内部类
public void getInner() {
Inner in = new Inner();
in.myInner();
}
//外部访问内部类
pulblic static void main(String args[]) {
Outer out = new Outer();
Outer.Inner in = out.new Inner();
in.myInner();
}
}
ii. 局部内部类(方法内部类):在外部类的某个方法内定义的类,与成员内部类不同,它相当于外部类的一个局部变量,修饰符只有final和abstract。
1. 只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。
2. 局部内部类对象不能使用该内部类所在方法的非final局部变量。因为方法的局部变量位于栈上,只存在于该方法的生命期内。当一个方法结束,其栈结构被删除,局部变量成为历史。但是该方法结束后,在方法内创建的内部类对象可能仍然存在于堆中!例如,如果对它的引用被传递到其他某些代码,并存储在一个成员变量内。正因为不能保证局部变量的存活期和方法内部类对象的一样长,所以内部类对象只能使用所在方法中被定义为final的局部变量。
3. 静态方法内的局部内部类没有this的引用。
a) 示例:
class Outer {
public void doSomething() {
final int a = 10;
class Inner {
public void myInner() {
System.out.println(a);
}
}
}
}
iii. 匿名内部类:没有名字的内部类。
1. 继承式的匿名内部类
class Car {
public void drive() {
System.out.println(“Driving a car!”);
}
}
class Temp {
public static void main(String[] args) {
Car car = new Car() {
pulbic void drive() {
System.out.println(“Driving another car!”);
}
};
car.drive();
}
}
2. 接口式的匿名内部类
interface Face {
public void drive();
}
class Temp {
public static void main(String[] args) {
Face face = new Face() {
public void drive() {
System.out.println();
}
};
face.drive();
}
}
3. 参数匿名内部类:顾名思义,将匿名内部类当成参数使用。
iv. 静态嵌套类:从技术上讲,静态嵌套类不属于内部类。因为内部类与外部类共享一种特殊关系,更确切地说是对实例的共享关系。而静态嵌套类则没有上述关系。它只是位置在另一个类的内部。因此也被称为顶级嵌套类。静态的含义是该内部类可以像其他静态成员一样,没有外部类对象时,也能够访问它。静态嵌套类不能访问外部类的成员和方法。
class Outer {
static class Inner{}
}
class Temp {
public static void main(String[] args) {
Outer.Inner n = new Outer.Inner();
}
}