可以将一个类的定义在另一个类或者一个方法内部(一般都是定义在类里面),在内部的类就称为内部类,在内部类的外部的类称为外部类。内部类可以在数据结构实现链表的结点等还有很多的地方使用它。然而内部类又分四种:静态内部类、实例内部类、局部内部类以及匿名内部类。
每一个内部类都有自己的字节码文件,对于内部类字节码文件就是外部类类名$内部类类名 ,对于匿名内部类字节码文件就是有些特殊是外部类类名$数字。
实例内部类
1.如何创建?
实例化一个内部类不能和之前直接实例化一样(之前:Person p = new Person),创建内部类则是需要先创建一个外部类out,然后再创建的外部类.创建内部类,下图就是我所说的实例化一个对象。
2. 在实例内部中,是否可以定义静态的成员变量?
在内部中,不可以定义静态变量,但是可以定义“常量”(即public static final int g = 7;)因为内部类依赖于外部类,必须外部类实例一个对象,内部类才能被创建,然而静态变量则是在创建外部类对象前就先实现的,这样这个静态变量就出现矛盾而报错。
3.当出现内部类与外部类数据成员一样时,怎没分辨这两者?
我们既可以在内部类方法中调用也可以在实例完一个对象后调用。在内部类方法中调用相同变量时采用就近原则;如果是this.变量名,那就需要看是谁调用的这个方法,那么这个this指的就是谁;如果想要实现外部类的变量, 就需要外部类类名.this.变量名。
总结一下:
- 外部类中的任何成员可以在实例内部类方法中直接访问;
- 实例内部类所处的位置与外部类成员位置相同,也受访问限定符(public、private)的约束;
- 在实例内部类方法中访问同名的成员,优先访问内部自己的,如果要访问外部同名成员,则需要外部类类名.this.同名成员;
- 实例内部类对象必须现有外部类对象的前提下才能创建;
- 实例内部类是我非静态方法中包含一个指向外部类对象的引用;
- 外部类方法中,不能直接访问实例内部类的成员,如果要访问比想要创建内部类的对象(普通对象的创建); 在其它的类中就需要外部类对象.new 内部类类名()。
class OuterClass{public int a = 1;private int b = 2;public static int c = 3;class InnerClass{public int a = 1111;public int d = 4;private int e = 5;//public static int f = 6;//静态方法最先创建,但是内部类又是依赖与外部类的,//就会出现矛盾,在f创建前必须要创建外部类,而这里的f则是在最先创建的外部类还没有实例化public void test() {System.out.println("内部类的test方法");System.out.println(a);//就近原则 1111System.out.println(this.a);//谁调用test方法谁就是this, System.out.println(OuterClass.this.a);System.out.println(d);System.out.println(e);}}public void test() {System.out.println("外部类的test方法");System.out.println(a);System.out.println(b);System.out.println(c);}
}public class Test{public static void main(String[] args) {//实例一个外部类对象OuterClass out = new OuterClass(); //实例一个内部类对象//InnerClass in = new InnerClass();//不能实例单独一个内部类 //所以在实例一个内部类时,一定要有一个内部类对象OuterClass.InnerClass out_in1 = out.new InnerClass();//外部类.创建内部类OuterClass.InnerClass out_in2 = new OuterClass().new InnerClass();//然后就可以调用内部类的方法及属性System.out.println(out_in1.d);out_in1.test();}
}
静态内部类
静态内部类的创建不需要创建外部类,直接外部类类名.内部类类名就可以创建内部类对象,还有在内部类中可以定义静态成员,其他的都和实例内部类相像。
匿名内部类
匿名内部类允许实例化时没有名字,并且只需要使用一次。它也和普通类创建一样抽象方法必须要继承等其他问题。
在匿名内部类中只能访问没有修改过的成员(变量的捕获)。
局部内部类
在方法中定义内部类,那么就是只能在该方法中使用。这个不过多说明,使用的次数较少。
使用次数是:静态内部类>匿名内部类>实例内部类>局部内部类