内部类:将一个类的定义放在另一个类的定义内部。
为什么需要内部类:
- 内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据。
- 内部类可以对同包中的其他类隐藏起来。
- 当需要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。
一、创建内部类
public class Parcel2 {
class Contents {
private int i = 11;
public int value() { return i; }
}
class Destination {
private String label;
Destination(String whereTo) {
label = whereTo;
}
String readLabel() { return label; }
}
public Destination to(String s) {
return new Destination(s);
}
public Contents contents() {
return new Contents();
}
public void ship(String dest) {
Contents c = contents();
Destination d = to(dest);
System.out.println(d.readLabel());
}
public static void main(String[] args) {
Parcel2 p = new Parcel2();
p.ship("Tasmania");
Parcel2 q = new Parcel2();
// Defining references to inner classes:
Contents c = q.contents();
Destination d = q.to("Borneo");
}
} /* Output:
Tasmania
*///:~
二、链接到外部类
内部类既可以访问自身的数据域,也可以访问创建它的外围类对象的数据域。
interface Selector {
boolean end();
Object current();
void next();
}
public class Sequence {
private Object[] items;
private int next = 0;
public Sequence(int size) { items = new Object[size]; }
public void add(Object x) {
if(next < items.length)
items[next++] = x;
}
private class SequenceSelector implements Selector {
private int i = 0;
public boolean end() { return i == items.length; }
public Object current() { return items[i]; }
public void next() { if(i < items.length) i++; }
}
public Selector selector() {
return new SequenceSelector();
}
public static void main(String[] args) {
Sequence sequence = new Sequence(10);
for(int i = 0; i < 10; i++)
sequence.add(Integer.toString(i));
Selector selector = sequence.selector();
while(!selector.end()) {
System.out.print(selector.current() + " ");
selector.next();
}
}
} /* Output:
0 1 2 3 4 5 6 7 8 9
*///:~
一、使用内部类访问对象状态
内部类既可以访问自身的数据域,也可以访问创建它的外围类对象的数据域。
内部类的对象总有一个隐式引用,它指向了创建它的外部类对象。但是这个引用在内部类的定义中是不可见的。