通过接口引用对象。

        应该优先使用接口而不是类来引用对象。如果有适合的接口类型存在,那么对于参数、返回值、变量和域来说,就都应该使用接口类型进行声明。只有当你利用构造器创建某个对象的时候,才真正需要引用这个对象的类。

        如果你养成了用接口作为类型的习惯,你的程序将会更加灵活。

        有一点值得注意:如果原来的实现提供了某种特殊的功能,而这种功能并不是这个接口的通用约定所要求的,并且周围的代码又依赖于这种功能,那么很关键的一点是,新的实现也要提供同样的功能。如果依赖于实现的任何特殊属性,就要在声明变量的地方给这些需求建立相应的文档说明。

        那么,为什么要改变实现呢?因为新的实现提供了更好的性能,或者因为他提供了期望得到的额外功能。有个真实的例子与ThreadLocal类有关。

        如果没有适合的接口存在,完全可以用类而不是接口来引用对象。例如值类,比如String和BigInteger。记住,值类很少会用多个实现编写。他们通常是final的,并且很少有对应的接口。使用这种值类作为参数、变量、域或者返回类型是再合适不过了。更一般地讲,如果具体类没有相关联的接口,不管他是否表示一个值,你都没有别的选择,只有通过他的类来引用他的对象。Random类就属于这汇总情形。

        不存在适当接口类型的第二种情形是,对象属于一个框架,而框架的基本类型就是类,不是接口。如果对象属于这种基于类的框架,就应该用相关的基类(往往是抽象类)来引用这个对象,而不是用他的实现类。java.util.TimerTask抽象类就属于这种情形。

        不存在适当接口类型的最后一种情形是,类实现了接口,但是他提供了接口中不存在的额外方法——例如LinkedHashMap。如果程序依赖于这些额外的方法,这种类就应该只被用来引用他的实例。他很少应该被用作参数类型。

        以上这些例子并不全面,而只是代表了一些“适合于用类来引用对象”的情形。实际上,给定的对象是否具有适当的接口应该是很显然的。如果是,用接口引用对象就会使程序更加灵活;如果不是,则使用类层次结构中提供了必要功能的最基础的类。

猜你喜欢

转载自blog.csdn.net/en_joker/article/details/81017733