内部类
概述
定义 | 可访问内容 | 创建方式 | |
---|---|---|---|
静态内部类 | 类内部的静态类 | 可访问外部类的所有静态变量和方法 | Outer.StaticInner inner = new Outer.Staticinner() |
成员内部类 | 类内部的非静态类 | 可访问外部类所有的变量和方法 | Outer.Inner inner = outer.new Inner(); |
局部内部类 | 方法中 | 定义在实例方法下的内部类:可访问所有变量和方法 定义在静态方法下的内部类:可访问所有静态变量和方法 | Inner inner = new Inner(); |
匿名内部类 | new 类/接口{} |
匿名内部类的特点:1.必须继承一个抽象类或实现一个接口
2.不能定义任何静态成员或方法
3.使用的形参,必须声明为final
4.必须要实现所有抽象方法,故不能是抽象的
代码演示
1.静态内部类
//静态内部类
public class Outer1 {
private static int radius = 1;
private static void method() {
System.out.println("static method");
}
static class StaticInner {
public void visit() {
System.out.println("visit outer static variable: " + radius);
System.out.println("visit outer static method: ");
method();
}
}
public static void main(String[] args) {
Outer1.StaticInner inner = new Outer1.StaticInner();
inner.visit();
}
}
2.成员内部类
//成员内部类
public class Outer2 {
private static int radius = 1;
private int count = 2;
private static void method1() {
System.out.println("static method");
}
private void method2() {
System.out.println("method");
}
class Inner {
public void visit() {
System.out.println("visit outer static variable: " + radius);
System.out.println("visit outer variable: " + count);
System.out.println("visit outer static method: ");
method1();
System.out.println("visit outer method: ");
method2();
}
}
public static void main(String[] args) {
Outer2 outer = new Outer2();
Outer2.Inner inner = outer.new Inner();
inner.visit();
}
}
3.局部内部类
//局部内部类
public class Outer3 {
private int out_a = 1;
private static int STATIC_B = 2;
//定义在普通方法下的局部内部类
public void testFuncClass() {
int inner_c = 3;
class Inner {
private void visit() {
System.out.println("外部变量: " + out_a);
System.out.println("外部静态变量: " + STATIC_B);
System.out.println("内部变量: " + inner_c);
}
}
Inner inner = new Inner();
inner.visit();
}
//定义在静态方法下的局部内部类
public static void testStaticFuncClass() {
int inner_d = 3;
class Inner {
private void visit() {
//System.out.println("外部变量: " + out_a); //编译错误,定义在静态方法下的局部类不能访问外部的实例变量
System.out.println("外部静态变量: " + STATIC_B);
System.out.println("内部变量: " + inner_d); //inner_d为常量
}
}
Inner inner = new Inner();
inner.visit();
}
public static void main(String[] args) {
Outer3 outer3 = new Outer3();
outer3.testFuncClass();
testStaticFuncClass();
}
}
4.匿名内部类
//匿名内部类
public class Outer4 {
private void test(final int i) { //匿名类使用的形参,声明为final
new Service() {
@Override
public void method() { //匿名内部类不能定义静态成员或方法
for (int j = 0; j < i; j++) {
System.out.println("匿名内部类");
}
}
}.method();
}
public static void main(String[] args) {
Outer4 outer4 = new Outer4();
outer4.test(5);
}
}
interface Service { //匿名内部类必须继承一个抽象类或者实现一个接口
void method();
}
优点
1.内部类可访问外部类的内容,包括私有数据
2.不为同一包的其他类所见,封装性好
3.多重继承,定义回调
局部内部类、匿名内部类访问的局部变量需要加final?
因为生命周期不一致,普通的局部变量,在方法结束后,会被销毁,而内部类对局部变量的引用仍存在。加了final的变量可保证内部类使用的变量与外层的局部变量区分开。