今天复习内部类
简介:
在类中定义的另一个类称为内部类。内部类可直接访问外部类的属性和方法,无需创建外部类对象。而外部类要访问内部类的属性和方法,则需创建内部类对象。当内部类与外部类存在同名变量或方法时,内部类的优先级更高。外部类的修饰符可为 public 或 default,内部类则可为 public、protected、default 或 private。
分类:
- 成员内部类(普通内部类):
- 定义在外部类的成员位置
- 可直接访问外部类的变量和方法(包括私有和静态修饰的)
- 不能使用 static 声明变量和方法
- 编译后生成的 class 文件命名为"外部类名$内部类名"
- 不能直接 new 内部类对象,必须通过外部类对象创建
示例:
public class Test {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.test();
}
}
class Outer {
private int x = 10;
private static int z = 20;
class Inner {
int y = 20;
public void test() {
System.out.println(x + z);
}
}
}
当外部类和内部类具有同名成员时,内部类默认访问自身成员。若要访问外部类成员,需使用 Outer.this
语法:
public void test() {
System.out.println(x + "\t" + Outer.this.x);
}
- 静态内部类:
- 使用 static 修饰的内部类
- 不能直接访问外部类的非静态成员
- 要访问外部类实例成员,需创建外部类对象
- 可声明静态变量和方法
- 创建对象时无需外部类实例
示例:
public class Test1 {
public static void main(String[] args) {
OuterStatic.InnerStatic innerStatic = new OuterStatic.InnerStatic();
innerStatic.test();
OuterStatic.InnerStatic.test1();
}
}
class OuterStatic {
private int x = 20;
public static void test1() {}
static class InnerStatic {
private static int y = 20;
public static void test1() {}
public void test() {
test1();
OuterStatic outerStatic = new OuterStatic();
System.out.println(outerStatic.x);
}
}
}
- 局部内部类:
- 定义在外部类的方法或代码块中
- 可直接访问外部类的所有成员(包括私有和静态的)
- 不能使用访问修饰符,但可用 final 修饰
- 作用范围仅限于定义它的方法或代码块
示例:
public class OuterLocal {
private int x = 10;
private static void test2() {}
public void testn() {}
public void test() {
int y = 10;
class InnerLocal {
public void test1() {
System.out.println(y);
}
}
InnerLocal local = new InnerLocal();
local.test1();
}
}
- 匿名内部类:
- 没有类名的嵌套类
- 用于只需使用一次的接口/父类方法实现
- 语法:
new 接口/父类()
局部内部类访问局部变量:
- JDK 1.8 之前,局部变量必须声明为 final
- JDK 1.8 之后,默认具有 final 特性,可访问但不能修改
- 使用 final 修饰可确保数据一致性