一般顶级类(如Object)或顶级接口是不会被嵌套的,只有它们嵌套其他的类。除了顶级类以外,按类定义的特性可以分为:
• 静态成员内部类
• 非静态成员内部类
• 局部内部类
• 匿名内部类
内部类可以访问它的外部类的成员,包括private成员,但内部类的成员只有在内部类的范围之内是可知的,不能被外部类使用。
内部类的主要好处:高内聚,低耦合。也就是说,内部类相当于外部类的密友,外部类与其他类相当于普通朋友,密友知道外部类的所有东西,普通朋友只能知道外部类所公布的东西。
接下来我们一个个来讨论:
(非静态)成员内部类
public class Outer1 {
private int age = 11;
class Inner { //内部类
private int age = 22;
public void display() {
System.out.println(Outer1.this.age); //访问外部类的age
System.out.println(this.age); //访问内部类的age
}
}
public static void main (String[] args) {
Outer1 out = new Outer1(); //先建立外部类对象
Outer1.Inner in = out.new Inner(); //根据外部类对象建立内部类对象
in.display(); //访问内部类方法
//Outer1.Inner in2 = new Outer1().new Inner(); //简写形式
//in2.display();
}
}
运行结果:
静态内部类
只有将某个内部类修饰为静态类,然后才能够在这个类中定义静态成员变量和成员方法。
静态内部类只能访问外部类的静态成员,不能访问外部类的非静态成员。
注意:静态内部类比较特殊,它的对象创建不需要外部类对象。
public class Outer2 {
private static int i = 1;
public static void outer_f1() {}
static class Inner {
static int inner_i = 100;
int inner_j = 200;
static void inner_f1() {
System.out.println("Outer.i = " + i);
outer_f1();
}
}
public static void main(String[] args) {
System.out.println(Inner.inner_i); //访问内部类的静态成员:内部类.静态成员
Inner.inner_f1();
Inner inner = new Inner(); //访问内部类非静态成员时,需实例化内部类
System.out.println(inner.inner_j);
}
运行结果:
局部内部类
也叫方法内部类,即在方法内部定义的内部类:
- 在局部内部类中,若定义的局部内部类的成员属性、局部内部类的成员方法参数以及外部类的成员属性同名,则如果是参数,可以直接访问,如果是局部内部类的成员属性,通过this.属性名来访问,如果是外部类的成员属性,可以通过外部类的类名.this.属性名来访问。
- 在局部内部类中,如果要访问外部类的局部变量,则此变量必须是final修饰的。
- 与非静态成员内部类类似,内部类的实例化必须先实例化外部类。
- 基本上起不到与外部类交互的作用,实际应用较少,只需了解它的相关用法即可。
public class Outer3 {
public void display() {
class Inner{ //局部内部类
}
}
}
匿名内部类
匿名内部类就是没有名字的局部内部类,也没有构造器,局部内部类的限制对其都有效。
interface Base {
public void fun1();
}
public class Outer4 {
public void callInner(Base a) {
a.fun1();
}
public static void main (String[] args) {
new Outer4().callInner(new Base() { //子类对象实现接口,没给对象取名
public void fun1() {
System.out.println("我实现了Base接口");
}
});
}
}
运行结果: