内部类:定义在另外一个类的范围内(这个范围可以是类也可以是函数,甚至是表达式)的类!
内部类有很多种,下面我们来介绍几种经常用到的内部类:
一:成员内部类!
特点:
1:成员内部类可以访问它的外部类的所有成员变量和方法不管是静态的还是非静态的。
2:在外部类里面创建成员内部类的实例:this.new 内部类名();
3:在外部类之外的类创建内部类的实例:(new 外部类名()).new 内部类名();
4:在内部类访问外部类的成员:外部类名.this.变量名
如下代码实例(运用在注释中体现了):
/*外部类*/ class OutClass { private int i = 1; private int j = 2; /*在外部类中创建内部类的实例*/ InnerClass inn = this.new InnerClass(); /* 定义一个成员内部类 */ public class InnerClass { private int inner = 8; public void workClass(){ /*从内部类中可以直接访问外部类的成员变量*/ System.out.println(i); /*也可以使用:外部类名.this.变量名 的方法访问外部变量*/ System.out.println(OutClass.this.j); } } } public class MyInnerClassTest { public static void main(String[] args) { /*在外部类以外的类中创建成员内部类的对象需要先创建外部类的对象实例*/ OutClass.InnerClass innerClass = (new OutClass()).new InnerClass(); /*调用内部类中的方法*/ innerClass.workClass(); } }
生成的.class文件中,成员内部类被编译为:外部类名$内部类名.class 如上代码中内部类会编译为OutClass$InnerClass.class【程序中的三个类都会生成字节码】
二:匿名内部类:
特点:
1:匿名内部类就是没有名字的局部内部类,不使用关键字class、extends、implements,没有构造方法,一般是使用它父类的无参构造方法来创建实例,匿名内部类隐式的继承了一个父类或实现了一个接口。
2:匿名内部类必须实现父类或接口中的所有抽象方法。
匿名内部类在安卓中用的非常多,如下代码示例:
/*设置rotate按钮的监听事件*/ rotate.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { /*获取rotate动画*/ Animation animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.rotate); /*设置动画*/ imgView.startAnimation(animation); } });
在生成的.class文件中,匿名内部类会编译成:外部类名$1.class的文件,数字1表示第几个匿名内部类,如,有两个匿名内部类,此时的.class文件就是:外部类名$1.class
和 外部类名$2.class。
三:静态内部类!
特点:
1:定义时加上static关键字。
2:静态内部类可以访问外部类的静态成员和静态方法,包括私有的静态成员和方法,但是非静态的就不能访问。
3:生成静态内部类对象的方式:new 外部类名.内部类名();
如下示例代码:
/*外部类*/ class OutClass { private int i = 1; private static int j = 2; /* 定义一个静态内部类 */ public static class StaticInnerClass { public void test(){ /*直接可以访问外部类中的静态变量和方法,私有的静态变量和方法也不例外*/ System.out.println(j); /*注:不能访问外部的非静态变量和方法*/ //System.out.println(i); } } } public class MyInnerClassTest { public static void main(String[] args) { /*创建静态内部类对象的方法:new 外部类名.内部类名*/ OutClass.StaticInnerClass staClass = new OutClass.StaticInnerClass(); /*调用内部类中的方法*/ staClass.test(); } }
静态内部类编译生成的.class文件为:外部类名$内部类名.class 如上述程序:OutClass$StaticInnerClass.class【这只是内部类的字节码哈,不要以为这个程序就只编译为这一个字节码文件,其他两个类也会生成字节码文件!】