将一个类的定义放在另一个类的内部,这就是内部类
内部类是一种非常有用的特性,因为他允许你把一些逻辑相关的类组织在一起,并控制位于内部的类的可见性。内部类能了解外围类,并且与之通信!!!
创建内部类:
创建内部类就如同你想的一样,把类的定义置于外围类的里面:
代码如下:
package inner;
/**
* Created by panther.dongdong on 2016/1/12.
*/
public class Parcel1 {
class Content {
private int i = 11;
public int value() {
return i;
}
}
class Destination {
private String label;
Destination(String whereTo) {
this.label = whereTo;
}
String readLabel() {
return label;
}
}
public void ship(String dest) {
Content content = new Content();
Destination destination = new Destination(dest);
System.out.println(destination.readLabel());
}
public static void main(String[] args) {
Parcel1 parcel1 = new Parcel1();
parcel1.ship("panther");
}
}
当我们在ship方法里使用内部类的时候,与使用其他类没有什么区别!!
更典型的方法是,外部类将有一个方法,该方法返回一个指向内部类的引用,就像在to()和contents()方法中看到的
package inner;
/**
* Created by panther.dongdong on 2016/1/12.
*/
public class Parce2 {
class Content {
private int i = 11;
public int value() {
return i;
}
}
class Destination {
private String label;
Destination(String whereTo) {
this.label = whereTo;
}
String readLabel() {
return label;
}
}
//指向内部类的引用
public Destination to(String s) {
return new Destination(s);
}
//指向内部类的引用
public Content content() {
return new Content();
}
public void ship(String dest) {
Content content = content();
Destination destination = to(dest);
System.out.println(destination.readLabel());
}
public static void main(String[] args) {
Parce2 parce2 = new Parce2(); //new 一个外围类
parce2.ship("panther");
Parce2 parce21 = new Parce2();
Parce2.Content content = parce21.content(); //new 一个内部类
Parce2.Destination destination = parce21.to("pan"); //new 一个内部类
}
}
如果想从外部的非静态方法之外的任意位置创建某个内部类的对象,那么必须像在main()方法里那样,具体的指明这个对象的类型:外围类.内部类
链接到外部类
当生成一个内部类对象时,此对象与制造它的外围对象之间有一种联系,所以它能访问其外围对象的所有成员,而不需要任何特许条件,此外内部类拥有其外围类的所有元素的访问权,如下所示:
package inner;
/**
* Created by panther.dongdong on 2016/1/12.
*/
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.println(selector.current());
selector.next();
}
}
}
Sequence类是一个固定大小的Object的数组,以类的形式包装了起来。可以调用add增加新对象,要获得Sequence中的每一个对象,可以使用Selector接口。这是迭代器模式设计的一个例子。Selector可以检测序列是否到了末尾了(end),访问当前对象(current)以及移到序列的下一个对象(next),因为selector是一个接口,所以别的类可以按照他们自己的方式来实现这个接口,并且别的方法以此接口为参数,来生成更加通用的代码
内部类自动拥有对外围类多有成员的访问权。这是如何做到的呢?
当某个外围类对象创建了一个内部类对象时,此内部类对象必定会秘密地捕获一个指向那个外围类对象的引用。然后当你访问外围类的成员时,就是用那个引用来选择外围类的成员,幸运的是,这些细节都是编译器帮你处理的!!!