内部类
定义在另外一个类中的类,内部类是个编译时的概念,一旦编译成功后,它就与外围类属于两个完全不同的类(内部类获取有外围类的引用),对于一个名为OuterClass的外围类和一个名为InnerClass的内部类,在编译成功后,会出现这样两个class文件:OuterClass.class和OuterClass$InnerClass.class。
作用:
1.内部类可以隐藏在外部类之内,不允许其他类直接访问,封装性更好。
2.内部类可以直接访问外部类的所有数据,包括私有数据。内部类使用起来更灵活
分类:
1.成员内部类
1.1 外部类要访问内部类要先实例化外部类,通过实例.new 内部类()产生内部类实例访问内部类数据,内部类和外部类可以有相同的变量和方法,优先访问自己的,内部类在实例化的时候获得外部类的引用,可使用外部类名.this访问外部类。
1.2 成员内部类可以无条件地访问外部类的成员,编译器会默认为成员内部类添加了一个指向外部类对象的引用.
1.3如果成员内部类Inner用private修饰,则只能在外部类的内部访问,如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问
1.4 成员内部类中不能存在任何static的变量和方法
引用网上简单示例:
public class OuterClass {
private String str;
public void outerDisplay(){
System.out.println("outerClass...");
}
public class InnerClass{
public void innerDisplay(){
//使用外围内的属性
str = "chenssy...";
System.out.println(str);
//使用外围内的方法
outerDisplay();
}
}
/*推荐使用getxxx()来获取成员内部类,尤其是该内部类的构造函数无参数时 */
public InnerClass getInnerClass(){
return new InnerClass();
}
public static void main(String[] args) {
OuterClass outer = new OuterClass();
OuterClass.InnerClass inner = outer.getInnerClass();
inner.innerDisplay();
}
}
chenssy...
outerClass...
创建成员内部类对象的一般形式为: 外部类类名.内部类类名 xxx = 外部类对象名.new 内部类类名()
2.静态内部类
static修饰的内部类,独立于外部类,可以在不创建外部类对象的情况下创建内部类的对象。静态内部类不持有指向外部类对象的引用,不能直接访问外部类的非静态成员,对于外部类的静态变量(不同名)可以直接使用变量名访问,同名的话使用类名.静态名访问
public class testmemberinnerclass {
private final int a;//空final
private static int b;//类加载时会赋初值给类变量
private static final int c;//final修饰的不会初始赋值
static {
c=0;
}
public testmemberinnerclass(int j,int l){
a=j;
System.out.println("构造a:"+a);
b=l;
System.out.println("构造b:"+b);
}
private class innerclass {
void m2_inner(int i, int k) {
b = k;
System.out.println("inner class a:" + a);
System.out.println("inner class b:" + b);
}
}
static class innerclass2 {
void m2_inner(int i, int k) {
b = k;
// System.out.println("inner class a:" + a);
testmemberinnerclass test=new testmemberinnerclass(10,11);
System.out.println("inner class b:" +test.a);
System.out.println("inner class b:" + b);
}
}
public static void main(){
testmemberinnerclass outer = new testmemberinnerclass(10,11);
innerclass inner = outer.new innerclass();// 必须通过包含内部类的外部类去访问内部类
inner.m2_inner(4, 5);
//创建静态内部类的方式
innerclass2 i2=new testmemberinnerclass.innerclass2();
}
}
创建静态内部类对象的一般形式为: 外部类类名.内部类类名 xxx = new 外部类类名.内部类类名()
3.方法内部类
局部内部类的访问仅限于方法内或者该作用域内,局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。
示例
public void m3(){
class methodinnerclass{
void print(){
System.out.println("方法内部类");
}
}
methodinnerclass methodinnerclass=new methodinnerclass();
methodinnerclass.print();
}
4.匿名内部类
匿名内部类没有构造器,没有访问修饰符格式 new method(){do};分号不可省略,另外new的时候类一定是要存在的,do重写或实现类的方法
匿名内部类在编译的时候由系统自动起名为Outter$1.class
匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写
局部(方法)内部类和匿名内部类只能访问局部final变量,因为到局部内部类的方法传参是值传递,在内部类的方法修改了参数对元参数无效造成数据不一致,所以就限定内部类方法中的局部变量和形参都必须用final进行限定,当所在方法的形参需要被匿名内部类使用,那么这个形参就必须为final。
示例
public A m2(final int count,String str){//匿名内部类使用到的变量必须设置成final,str未在匿名内部类使用所以不需要设置成final
System.out.println("进入m2方法");
return new A(){
public void domth() {
// TODO Auto-generated method stub
System.out.println("匿名内部类"+count);
}
};//分号表示匿名内部类的终结,不可少
}
interface A{//此接口一定要有,否则匿名内部类出错类
void domth();
}
public static void main(String args[]) {
testmemberinnerclass outer3 = new testmemberinnerclass(10,11);
A a=outer3.m2(199,"abc");
a.domth();
}
}
使用内部类作用
1.每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响,内部类的存在使得Java的多继承机制变得更加完善
2.方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。
3.方便编写事件驱动程序
4.方便编写线程