内部类之 连接到外部类

我前一篇博客开始,内部类似乎还只是一种名字隐藏和组织代码的模式。这是是很有用,但还不是最引人注目的,它还有其它的用途。当生成一个内部类的对象时,此对象与制造它的外围对象之间就有了一种联系,所以它能访问其外围对象的所有成员,而不需要任何特殊的操作。此外,内部类还拥有其外围类的所有元素的访问权。

interface Selector{

    boolean end();

    Object current();

    void next();
}

public class Sequence {

    private Object[] items;

    private int next = 0;

    private Sequence(int size){items = new Object[size];}

    public void add(Object x){
        items[next++] = x;
    }

    private class SequenceSelector implements Selector{

        private int i = 0;

        @Override
        public boolean end() {
            return i == items.length;
        }

        @Override
        public Object current() {
            return items[i];
        }

        @Override
        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()在序列末增加新的Object(只要还有空间)。要获取Sequence中的每一个对象,可以使用Selector接口。这是“迭代器”设计模式的一个例子。Selector允许你检查序列是否已经到了末尾了(end()),访问当前对象(current()),以及移到序列的下一个对象(next())。因为Selector是一个接口,所以别的可以按它们自己的方式来实现这个接口,并且别的方法能以此接口为参数,来生成更加通用的代码。

所有内部类自动拥有对其外围类所有成员的访问权,这是如何做到的呢?当某个外围类的对象创建了一个内部类对象时,此内部类对象必会秘密地捕获一个指向那个外围类的对象的引用。然后,在你访问此外围类的成员时,就是那个引用来选择外围类的成员。幸运的是,编译器会帮你处理所有的细节,但是你现在可以看到,内部类的对象只能在与其外围类的对象相关联的情况下才能被创建(就像你看到的那样,内部类是非static类时)。构造内部类对象是,需要一个指向其外围类对象的引用,如果编译器访问不到这个引用就会报错。不过绝大多数时候都无需程序员操心。

你可能感兴趣的:(java)