最近总被茫茫多的bug压在身上,深感烦躁,而且连续几天没有看源码了,鸭梨山大。最近忙里偷闲看了下内部类,赶紧找个时间把对它的一些感触记下来。
让我们一起来看下,内部类在android中的使用。
所谓内部类,顾名思义,是定义在类内部的类。
ok,来个简单的例子先。
package Test;
class Outer
{
private int a=100;
class Inner{
private int a=50;
void print(){
int a=30;
System.out.println(a); //30
System.out.println(this.a); //50
System.out.println(Outer.this.a); //100
}
}
void print(){
Inner p=new Inner();
p.print();
}
Inner getInner(){
return new Inner();
}
}
public class Test{
public static void main(String [] args){
Outer o=new Outer();
Outer.Inner fi= o.getInner();
fi.print();
}
}
这个例子很简答,打印出来的正确的值我也写在注释中了,但是,这个例子说明了内部类的两个重要的特性。
1.内部类拥有其外围类的所有元素的访问权
2.外部类必须指明内部类的对象类型,利用内部类对象访问内部类成员
我们可以从这个简单的例子中简要的分析下,inner类能访问outer类的a变量,尽管a是private的。而要引用inner类对象的时候,必须显示的指明outer.inner。
这是两点很重要的特性。好的,接下来,让我们放松一下,做个选择题。
下面的这几个类,那几个用到了内部类呢?
A.RIL.java
B.Button.setClickListener(new listener(){ onclick(); })
C.parcelable.java
D.RILRequest.java
下面我们来简单的分析下,首先我们来找到源码中对应的类。
先来到RIL.java,很明显,它里面不止一个内部类,比如RILSender。那A显然是正确答案咯
我们接着分析B,这其实是一种匿名内部类,所谓匿名,就是它没有名字。也就意味着,这个类根本就没有构造器。其实,new listener(){ onclick(); }是一个对象。其实它是这样实现的。假如有一个calss A实现了listener接口并复写了onclick函数,然后,我们生成了一个A对象,接着我们对这个A对象做了一次向上转型。
Class A implement listener{ onclick();}
A a = new A();
a = (listener)a;
这三步其实就是B中的那一步,所以,很显然,B也是正确答案
接下来,我们分析C,parcelable是一个接口,但是,它里面还有两个接口,它是不是内部类呢,不是的,它是嵌套接口。
ok,现在只剩下D了,RILRequest写在RIL.java中,它是不是呢,不是的,它们只是在同一个java文件中,是平级的关系,编译出来是两个class文件,如果是内部类,那么编译出来的形式一定是我们最前面的例子中的outer.class,outer$inner.class这种形式的,后面的就是内部类的class文件。
内部类有很多作用,我只简单的聊聊很容易理解的一种,内部类可以用来编写测试用例,因为内部类对外部类是没有影响的,那么可以在内部类里打印外部类的变量值用来测试。