所谓内部类就是在一个类内部进行其他类结构的嵌套操作。
它体现了一种代码的隐藏机制和访问控制机制。内部类与所在外部类有一定的关系,往往只有该外部类调用此内部类,所以没有必要专门用一个Java文件存放这个类。
内部类种类
内部类分为四种:静态内部类、成员内部类、局部内部类、匿名内部类。
静态内部类
public class TestInnerClass { /** * 静态变量 */ private static int num1 = 1; public static int num2 = 2; /** * 静态内部类 */ public static class StaticInner { public void test() { System.out.println("StaticInner: " + (num1 + num2)); } } /** * 外部类方法 */ public void print(){ StaticInner staticInner = new StaticInner(); staticInner.test(); } }
说明:
- 定义类时加上static关键字。
- 不能和外部类名字相同。
- 被编译成一个完全独立的.class文件(名称为OuterClass$InnerClass.class的形式)。
- 只可以访问外部类的静态成员和静态方法,包括了私有的静态成员和方法。
- 生成静态内部类对象的方式为:OuterClass.InnerClass inner = new OuterClass.InnerClass();
成员内部类
public class TestClass { /** * 成员变量 */ private static int num1 = 1; public static int num2 = 2; private int num3 = 3; public int num4 = 4; /** * 成员内部类 */ public class MemberInner { public void test() { System.out.println("MemberInner: " + (num1 + num2 + num3 + num4)); } } /** * 外部类方法 */ public void print(){ TestClass testClass = new TestClass(); TestClass.MemberInner memberInner = testClass.new MemberInner(); memberInner.test(); } }
说明:
- 静态内部类去掉static关键字就是成员内部类。
- 成员内部类和静态内部类可以类比为非静态的成员变量和静态的成员变量。
- 成员内部类就像一个实例变量。
- 它可以访问它的外部类的所有成员变量和方法,不管是静态的还是非静态的都可以。
- 在外部类里面创建成员内部类的实例:this.new Innerclass();
- 在外部类之外创建内部类的实例:(new Outerclass()).new Innerclass();
局部内部类
public class TestClass { /** * 成员变量 */ private static int num1 = 1; public static int num2 = 2; private int num3 = 3; public int num4 = 4; /** * 外部类方法 */ public void print() { final int num5 = 5; class LocalInner { public void test() { System.out.println("LocalInner: " + (num1 + num2 + num3 + num4 + num5)); } } new LocalInner().test(); } }
说明:
- 局部内部类定义在方法中,比方法的范围还小。是内部类中最少用到的一种类型。
- 像局部变量一样,不能被public, protected, private和static修饰
- 只能访问方法中定义的final类型的局部变量
- 局部内部类在方法中定义,所以只能在方法中使用,即只能在方法当中生成局部内部类的实例并且调用其方法
匿名内部类
public class NiMing { /** * 外部类方法 */ public void print() { T t = new T() { @Override public void run() { System.out.println("t..."); } }; t.run(); } } interface T { public void run(); }
说明:
- 匿名内部类就是没有名字的局部内部类,不使用关键字class, extends, implements, 没有构造方法。
- 一个匿名内部类一定是在 new 后面,用其隐含实现一个接口或实现一个类。
- 匿名内部类使用得比较多,通常是作为一个方法参数。
- 生成的.class文件中,匿名类会生成OuterClass$1.class文件,数字根据是第几个匿名类而类推。
- 内部类只能访问外部类的静态变量或静态方法。
- 内部类当中的 this 指的是匿名内部类本身,如果使用外部类中的 this,则“外部类.this”。
内部类的使用场景
场景一:当某个类除了它的外部类,不再被其他的类使用时
场景二:解决一些非面向对象的语句块
场景三:一些多算法场合
场景四:适当使用内部类,使得代码更加灵活和富有扩展性