内部类顾名思义,就是定义在一个类内部的类,使用内部类的场景主要有三种:
内部类的方法可以访问外部类所定义的数据,包括私有属性;
内部类可以对同一个包中的类实现隐藏;
如果想定义一个回调函数但不想编写大量代码,可以使用内部类。
使用内部类可以访问外部对象的状态
class OuterClass {
private String name;
private boolean isOk;
public class InnerClass {
public void sayName() {
if (isOk) {
System.out.println("name:" + name);
} else {
System.out.println("no name");
}
}
}
}
内部类既可以访问它自身的数据区域,也可以访问它外部类的数据域;
在InnerClass中,其实总是有一个OuterClass的隐式引用;
内部类的特殊语法规则
我们知道在内部类总是有一个外部类的隐式引用,那么在内部类访问外部类的属性时其实正确的语法是:
// 访问OuterClass类属性的标准语法
if(OuterClass.this.isOk) System.out.println(OuterClass.this.name);
反过来,如果在外部需要访问内部类,那么就需要这样:
OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
innerClass.sayName();
在外部类的作用域之外,也可以通过OuterClass.InnerClass得到引用。
内部类中所有声明的静态域都必须是final,原因在于我们希望一个静态域只 有一个实例, 不过对于每个外部对象, 会分别有一个单独的内部类实例。 如果这个域不是final, 它可能就不是唯一的。
允许有静态方法, 但只能访问外部类的静态域和方法。
局部内部类
如果某个内部类只需要在创建的时候使用一次,那么就可以使用局部内部类来替换:
class OuterClass {
private String name;
private static boolean isOk;
class InnerClass{
public void sayName() {
if (isOk) {
System.out.println(name);
}
}
}
}
局部内部类不能使用public或者private等访问修饰符声明,因为它的作用域被限定在声明局部内部类的这个块当中,它的优势也很明显,就是对外部完全隐藏。
局部类的方法只可以引用定义为final修饰的局部变量。保证局部类中的拷贝和局部变量保持一致。
匿名内部类
将局部内部类再深入一步,创建的俄时候无需指定类名,而把方法的声明放在超类或者接口当中,创建的地方只做方法的实现。
静态内部类
我们知道在一般的内部类中,会有一个隐式的外部类的引用,但是有时候只是为了把一个类隐藏在内部,而不需要这个隐式 的外部类引用,就可以将内部类声明为static的,就取消了外部类的隐式引用,叫做静态内部类。