普通内部类
内部类可以让你把一些逻辑相关的结构组织在一起。并且可以访问外部类的全部内容。
这样的特性使得内部类,可以完成一些组合或是继承不能完成的任务。
例如 :
public class Outer {
void f() {
System.out.println("DotThis.f()");
}
public class Inner {
public Outer outer() {
return Outer.this;
}
}
public Inner inner() {
return new Inner();
}
public static void main(String[] args) {
Outer dt = new Outer();
Outer.Inner dti = dt.inner();
dti.outer().f();
}
}
这是一个简单的内部类,他有一个方法,返回他的外部类的引用。通过OutterClass.this 语法可以使内部类访问到外部类的内容。
内部类的一个很大的用处是在向外提供一个接口的引用。他可以自由的访问外部类所有的内容而调用者并不知道他是一个内部类的实现
例如:
interface Iterator{
public Object next();
}
public class ArrayList extend MyList{
private transient Object[] elementData;
private int size;
public Iterator iterator(){
return new Itr();
}
private class Itr implements Iterator{
int current=0;
public Object next() {
Object temp=ArrayList.this.elementData[size-1];
if (current < size) {
temp = elementData[current];
current++;
}
return temp;
}
}
}
当调用者调用的时候,他并不知道iterator是由一个内部类实现的。这样做的好处是可以让Arraylist不必实现Interator接口。让ArrayList更纯洁(因为ArrayList不用完成一个Iterator的功能,他只需要提供一个引用就可以)。
并且如果 Interator 不是一个接口。而是一个类。 那么内部类是唯一的一个办法让ArrayList继承多个类。
内部类是Java中实现必包的一种方式。必包简单的理解就是一个对象可以访问创建他时候的环境。内部类天生就具备了这个性质。他可以访问创建他时,外部类所有的信息。
在Java中回调的实现也可以运用内部类。在外部类已经有了一个需要回调接口的实现时。但是此实现并不是回调函数需要的。那么只有内部类能解决这个问题。
例如:
interface Incrementable {
void increment();
}
class MyIncrement {
public void increment() { print("Other operation"); }
static void f(MyIncrement mi) { mi.increment(); }
}class Callee2 extends MyIncrement {
private int i = 0;
public void increment() {
super.increment();
i++;
print(i);
}
private class Closure implements Incrementable {
public void increment() {
System.out.println("correct increment");
}
}
Incrementable getCallbackReference() {
return new Closure();
}
}
class Caller {
private Incrementable callbackReference;
Caller(Incrementable cbh) { callbackReference = cbh; }
void go() { callbackReference.increment(); }
}
在此例中callee1已经有了自己的increment方法。但是为了实现回调的目的。他也需要实现increment方法。内部类解决了这个问题。内部类自己实现了回调方法。并且可以利用所有外部类的属性与方法,而且不会干扰外部类increment方法。既保证了原方法的不便也保证了回调的目的。
嵌套类
当内部类有static修饰的时候,它就成了一个嵌套类。他只不过是类之间的嵌套。没有其他多余的功能。他不能访问外部对象的属性(只能访问static的)。也就没有了对不同对象的区别对待等情况。
局部内部类
当一个内部类在一个方法的里面,他就成了局部内部类。局部内部类和内部类一样可以访问外部类所有的属性并且可以访问参数(必须要用final修饰)。
public class Outer{
private void internalTracking(boolean b) {
if(b) {
class Inner{
private String id;
Inner (String s) {
id = s;
}
String getSlip() { return id; }
}
Innerts = new Inner("slip");
String s = ts.getSlip();
}
}
至于他为什么只能访问final请
参见。
匿名内部类
匿名内部类就是一个没有名字的内部类。一般为局部内部类。在return的时候返回一个内部类。匿名内部类的匿名是因为名字不感兴趣。他只用一次,只在这里用。所以不需要名字。
public class Outer{
public Contents contents() {
return new Contents() {
private int i = 11;
public int value() { return i; }
};
}