在现实生活中,我们会对事物建模,将事物模拟成对象,对象是现实世界映射到程序语言的模型,是实际待解问题的抽象,这就是OOP语言的抽象机制。假设一个人,有状态和行为之分,如状态有悲伤、高兴...行为有跑、跳、唱歌。犹如对象有字段和方法一样,方法就是用来改变状态(字段)从而产生“副作用”或者更常见的得到一个返回值,这些基本的OOP概念我就不多说了,学Java的都知道。。
如果有很多对象都有共同的“面貌”,我们就会想到把它们抽象成一个接口。我们这里讨论的不是多态和向上转型机制,也不是给你讲何时用abstract何时用interface,而是讲实现接口和被操作对象的关系,是接口与对象分离呢?还是将接口封装在对象中?
首先来讨论第一种:接口与对象的分离。大多数人会想到为对象写一个简单的JavaBean,然后将接口在另一个文件中实现,通过import机制把JavaBean导入接口实现中,而在实际应用的时候只是调用接口实现的方法,就能轻而易举的对JavaBean进行操作。但是,如果在项目很大的时候,JavaBean很多的时候,这么多接口该怎么管理呢?看到这里,我们是不是再抽象下,我们把这么多接口放进一个“工厂”里,然后所有的Bean通过这个“工厂”完成我们对它们的“加工”(操作)。这就是工厂模式,这样做的好处是:你提供给我一个工厂,我不管这个工厂里有些什么,我只管我的原料(JavaBean)通过你那个工厂就会得到我想要的产品(结果)!这也说明,设计模式它不是工具,而是一种思想!
还有一种情况,如果接口对于某个对象改变其行为只占很少的分量,亦即是说这个对象自己本身也有很多方法,而接口只是与其他对象有相似的面貌罢了,那么我们还要花费心思单独写一个接口实现吗?答案当然不是,我们何必不把这个接口封装在对象中呢?接口也是类,这样我们就想到了内部类,对!就是内部类!考虑下面一段代码:
interface Selector
{
boolean end();
Object current();
void next();
}
public class Sequence
{
private Object[] objects;
private int next = 0;
public Sequence(int size){objects = new Object[size];}
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();}
//...代码没写完,只是勾出了大致的轮廓
}
我们用内部类的方式将Selector的接口实现了,然后用一个方法getSlelector来返回这个内部类对象生成的引用,这样就相当于我们把接口用一个方法实现了,只要:
Sequence sequence = new Sequence();
Selector selector = sequence.getSequence();
就可以取得操纵sequence对象中字段的接口,这样感觉是不是把接口封装在一个对象了?更确切地说是封装在对象中的一个方法中了!当某个外围类的对象创建了一个内部类对象时,此内部类对象必定会保存一个指向那个外围类对象的引用。这就是为什么内部类自动拥有对外围类所有成员的访问权。
试想一下,如果Sequence.java不使用内部类,就必须声明“Sequence是一个Selector”。对于某个特定的Sequence只能有一个Selector。但使用内部类就很容易拥有另一个方法getRSelector(),用它来生成一个反方向遍历序列的Selector。
这篇文章不是来列举内部类的好处的,内部类的好处不止这些,他在某些设计模式里面占有很重要的位置,比如java swing,它是swing应用程序框架实现的主要方法,也使GUI程序变得如此优美,我最喜欢的就是Java的优美。