链接到外部类

到目前为止,似乎内部类还只是一种隐藏命名和组织代码的模式,这些是很有用,但还不
是最引人注目的。然而,它还有其他的用途。当你生成一个内部类的对象时,此对象与制
造它的外围类的对象(enclosing object)之间就有了一种联系,所以它能访问其外围对
象的所有成员,而不需要任何特殊条件。此外,内部类还拥有其外围类的所有元素的访问
权3。下面的例子展示了这点:


//: c08:Sequence.java
// Holds a sequence of Objects.
import com.bruceeckel.simpletest.*; 


interface Selector { 
boolean end(); 
  Object current();
void next(); 
}


public class Sequence { 
private static Test monitor = new Test(); 

private Object[] objects; 

private int next = 0;
public Sequence(int size) { objects = new Object[size]; } 
public void add(Object x) { 
if(next < objects.length) 
      objects[next++] = x; 
  }
private class SSelector implements Selector { 
private int i = 0; 
public boolean end() { return i == objects.length; } 
public Object current() { return objects[i]; } 
public void next() { if(i < objects.length) i++; }
  }
public Selector getSelector() { return new SSelector(); }
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.getSelector(); 
while(!selector.end()) { 
      System.out.println(selector.current()); 
      selector.next();
    }
    monitor.expect(new String[] { 
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9"
    });
  }
} ///:~


Sequence 类只是一个固定大小的 Object 数组,以类的形式包装了起来。你可以调用
add(),在序列的尾端增加一个新的 Object(只要还有空间)。要获取 Sequence 中的每
一个对象,可以使用 Selector 接口,方法 end()允许你检查序列是否到末尾了,current()
查看当前对象,next() 移到序列中的下一个对象。因为 Selector 是一个接口,所以别的
类可以按它们自己的方式来实现这个接口,并且许多方法能以此接口为参数,来生成通用
的代码。
这里,SSelector 是提供 Selector 功能的 private 类。可以看到,在 main()中创建了一
个 Sequence,并向其中添加了一些 String 对象。然后通过调用 getSelector()获取一个
Selector,并用它在 Sequence 中移动和选择每一个元素。


最初看到 SSelector,可能会觉得它只不过是另一个内部类罢了。但请仔细观察它。注意
方法 end(),current(),和 next()都用到了 objects,这是一个引用,它并不是 SSelector
的一部分,而是外围类的一个 private 成员。所以内部类可以访问其外围类的方法和属性,
就像自己拥有它们似的。这带来了很大的方便,就如前面的例子所示。


内部类自动拥有对其外围类所有成员的访问权。这是如何做到的呢?当某个外围类的对象
创建了一个内部类对象时,此内部类对象必定会保存一个指向那个外围类对象的引用。然
后,在你访问此外围类的成员时,就是用那个“隐藏的”引用来选择外围类的成员。幸运
的是,编译器会帮你处理所有的细节,但你现在也知道了:内部类的对象只能在与其外围
类的对象相关联的情况下才能被创建。构建内部类对象时,需要一个指向其外围类对象的
引用,如果编译器访问不到这个引用就会报错。不过绝大多数时候这都无需程序员操心。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值