Java无难事:详解Java编程核心思想与技术
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

7.3 内部类与接口

img

扫码看视频

当内部类与接口组合在一起使用的时候,就能真正展现内部类的实用性了。让内部类实现一个接口,然后通过接口变量来引用这个内部类的实例,于是不用再和内部类的名称打交道,更重要的是可以屏蔽内部类的实现细节。

我们看代码7.7。

img

StringHolder类的作用是用于存储字符串,并提供字符串的迭代功能。

在这个例子中,我们定义了一个Iterator的接口,然后让StringHolder类的内部类StringIterator实现了这个接口。StringHolder类还给出了一个iterator方法,方法的返回类型是Iterator接口类型,方法内部创建了一个内部类StringIterator的对象,并返回它,该对象会被向上转型为接口类型。当需要使用这个内部类的实例时,调用外部类对象的iterator方法,并通过Iterator接口类型的变量来引用该对象即可,就像代码中“Iterator it = sh.iterator();”展示的一样,这样就不需要与内部类的名称打交道了。既然不需要直接访问内部类,为了更好地屏蔽内部类的实现细节,我们将该类声明为private,如同外部类的其他私有成员一样,我们将无法在外部类之外访问这个内部类。

程序的运行结果是:

img

提示:这段代码使用了迭代器(Iterator)设计模式。在Java的类库中,有Iterator和Iterable接口,当外部类实现了Iterable接口,并且有一个内部类实现了Iterator接口之后,就可以使用“for each”循环来遍历外部类中的元素了。

StringHolder类内部的实现采用数组来存储字符串,假如现在我们想给用户多一些选择,比如以链表来存储字符串,那么就可以再编写一个类,该类的内部类同样实现Iterator接口,对于用户来说,遍历字符串的方式都是一样的,都是通过Iterator接口声明的方法来遍历的,而外部类采用什么存储方式,具体怎么实现的存储则不需要关心。如果考虑到让新编写的类能够无缝替换旧的类,则可以让新旧两个类实现同样的接口,比如Iterable接口,该接口声明一个方法:Iterator iterator(),由于新旧两个类实现了相同的接口,所以用户就知道它们都有iterator方法,可以得到Iterator接口类型的对象,至于该对象实际的内部类实现根本无须关心,这实际上就是迭代器设计模式的应用了。读者可以根据这里给出的思路,给出新的存储方式的类实现。