其实,在日常应用中我们常常用到List list = new ArrayList()这种形式,这实际上是面向父类编程的一种体现。list引用指向ArrayList的实例,由于java成员方法的动态绑定机制,list在调用add,remove的方法的时候先看父类有没有实现,再看引用的子类有没有覆盖,如果覆盖了,则调用子类方法。这样有一点好处,后期如果发现引用这个子类不合适,只修改引用指向的实例类型即可。即只把new ArrayList()改成new 别的。如果声明写死了,ArrayList list = new ArrayList(),如果调用了ArrayList独有,List没有的方法,那就杯具了,得把相应调用的地方也给改了。
事实上,面向父类虽然一定程度上具有可扩展性,但并没有实现真正的解耦,改动创建实例的代码依然有很大的工作量,要想获得真正的可扩展性,需要引用工厂模式把创建对象的的行为包装起来。工厂负责提供对象,内部包含创建对象的逻辑。外部需要更换对象,只需要改动工厂内部创建对象的逻辑即可。工厂模式是把程序中会变动的逻辑移动到工厂类里面了,当系统类较多时,才系统扩展时需要经常改变工厂类中的代码。采用Ioc设计思想后,程序将会有更好的扩展性。spring容器将会根据配置文件创建调用者对象,同时把被调用的对象的实例化对象通过构造函数或set()方法的形式注入到调用者对象中。当需要把被调用对象改动的时候,只需修改配置文件,不需要改代码。改变了调用者依赖被调用者的局面,开发人员不需要关注对象如何被创建的,通过修改配置文件可以实现被调用对象的”热插拔“。
java的每个非static方法都相当于C++的虚函数,运行时决定其类型,这也是java比C++面向对象特性完善的一个原因吧。