详解Java内部类
前言
内部类的主要作用:
1. 内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。
2. 内部类的方法可以直接访问外部类的所有数据,包括私有的数据。
内部类可分为四种:普通内部类(成员内部类)、静态内部类、匿名内部类、局部内部类。
普通内部类
定义很简单,在一个类里面作为类的一个字段直接定义就可以了,例:
public class OuterClass { public class InnerClass { } }
public class OuterClass { public int a = 1; private int b = 2; public OuterClass() { // 在外部类对象内部,直接通过 new InnerClass(); 创建内部类对象 InnerClass innerClass = new InnerClass(); //getSimpleName() 返回源代码中给出的基础类的简单名称,如果基础类是匿名的,则返回空字符串 System.out.println("创建" + this.getClass().getSimpleName() + "对象"); System.out.println("其内部类的 c 字段的值为: " + innerClass.c); System.out.println("其内部类的 d 字段的值为: " + innerClass.d); } public class InnerClass { public int c = 1; private int d = 2; public InnerClass(){ System.out.println("创建 " + this.getClass().getSimpleName() + " 对象"); System.out.println("其外部类的 a 字段的值为: " + a); System.out.println("其外部类的 b 字段的值为: " + b); } } public static void main(String[] args) { OuterClass outerClass = new OuterClass(); //不在外部类内部,不能直接使用内部类创建对象。应该使用:内部类 对象名 = 外部类对象.new 内部类构造器(); 的方式创建内部类对象 //InnerClass innerClass = new InnerClass(); 会报错 //InnerClass innerClass = outerClass.new InnerClass();正确 } } /* 返回结果: 创建 InnerClass 对象 其外部类的 a 字段的值为: 1 其外部类的 b 字段的值为: 2 创建OuterClass对象 其内部类的 c 字段的值为: 1 其内部类的 d 字段的值为: 2 */
注意要点:
1、普通内部类可以无条件访问外部类的所有成员的属性和方法(包括private成员和静态成员)
2、如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,需要使用这种方式访问: 外部类 .
this
. 成员变量(
方法)
3、外部类是不能直接使用内部类的成员和方法,可先创建内部类的对象,然后通过内部类的对象来访问其成员变量和方法。内部类 对象名 = 外部类对象.new 内部类构造器( );
静态内部类
1、静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问
2、如果外部类的静态成员与内部类的成员名称相同,可通过“外部类名.静态成员”访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员
3、创建静态内部类的对象时,分为两种:a、在外部类的 mian主方法里 不需要创建外部类的对象,可以直接使用 静态内部类 对象名= new 静态内部类();
b、在测试类(即在外部类 外面的类) 需要这样 Outer.Inner in = new Outer.Inner();//(创建静态内部类对象)
局部内部类
1、局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
2、局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。
匿名内部类
匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。
匿名内部类在编译的时候由系统自动起名为Outter$1.class。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
同样的,匿名内部类也是不能有访问修饰符和static修饰符的。