提高Java代码重用性方法 措施二:把参数类型改成接口
2009-10-22 16:54
337 查看
措施二:把参数类型改成接口
正如Allen Holub在《Build User Interfaces for Object-Oriented Systems》中所指出的,在面向对象编程中,代码重用真正的要点在于通过接口参数类型利用多态性,而不是通过类继承:
“……我们通过对接口而不是对类编程达到代码重用的目的。如果某个方法的所有参数都是对一些已知接口的引用,那么这个方法就能够操作这样一些对象:当我们编写方法的代码时,这些对象的类甚至还不存在。从技术上说,可重用的是方法,而不是传递给方法的对象。”
在“措施一”得到的结果上应用Holub的看法,当某块代码能够编写为独立的全局过程时,只要把它所有类形式的参数改为接口形式,我们就可以进一步提高它的可重用能力。经过这个改动之后,过程的参数可以是实现了该接口的所有类的对象,而不仅仅是原来的类所创建的对象。由此,过程将能够对可能存在的大量的对象类型进行操作。
例如,假设有这样一个全局静态方法:
static public boolean contains(Rectangle rect, int x, int y) {...}
这个方法用于检查指定的点是否包含在矩形里面。在这个例子中,rect参数的类型可以从Rectangle类改变为接口类型,如下所示:
static public boolean contains(Rectangular rect, int x, int y) {...}
而Rectangular接口的定义是:
public interface Rectangular {Rectangle getBounds();}
现在,所有可以描述为矩形的类(即,实现了Rectangular接口的类)所创建的对象都可以作为提供给pRectangular.contains()的rect参数。通过放宽参数类型的限制,我们使方法具有更好的可重用性。
不过,对于上面这个例子,Rectangular接口的getBounds方法返回 Rectangle,你可能会怀疑这么做是否真正值得。换言之,如果我们知道传入过程的对象会在被调用时返回一个Rectangle,为什么不直接传入 Rectangle取代接口类型呢?之所以不这么做,最重要的原因与集合有关。让我们假设有这样一个方法:
static public boolean areAnyOverlapping(Collection rects) {...}
该方法用于检查给定集合中的任意矩形对象是否重叠。在这个方法的内部,当我们用循环依次访问集合中的各个对象时,如果我们不能把对象cast成为 Rectangular之类的接口类型,又如何能够访问对象的矩形区域呢?唯一的选择是把对象 cast成为它特有的类形式(我们知道它有一个方法可以返回矩形),它意味着方法必须事先知道它所操作的对象类型,从而使得方法的重用只限于那几种对象类型。而这正是前面这个措施力图先行避免的问题!
正如Allen Holub在《Build User Interfaces for Object-Oriented Systems》中所指出的,在面向对象编程中,代码重用真正的要点在于通过接口参数类型利用多态性,而不是通过类继承:
“……我们通过对接口而不是对类编程达到代码重用的目的。如果某个方法的所有参数都是对一些已知接口的引用,那么这个方法就能够操作这样一些对象:当我们编写方法的代码时,这些对象的类甚至还不存在。从技术上说,可重用的是方法,而不是传递给方法的对象。”
在“措施一”得到的结果上应用Holub的看法,当某块代码能够编写为独立的全局过程时,只要把它所有类形式的参数改为接口形式,我们就可以进一步提高它的可重用能力。经过这个改动之后,过程的参数可以是实现了该接口的所有类的对象,而不仅仅是原来的类所创建的对象。由此,过程将能够对可能存在的大量的对象类型进行操作。
例如,假设有这样一个全局静态方法:
static public boolean contains(Rectangle rect, int x, int y) {...}
这个方法用于检查指定的点是否包含在矩形里面。在这个例子中,rect参数的类型可以从Rectangle类改变为接口类型,如下所示:
static public boolean contains(Rectangular rect, int x, int y) {...}
而Rectangular接口的定义是:
public interface Rectangular {Rectangle getBounds();}
现在,所有可以描述为矩形的类(即,实现了Rectangular接口的类)所创建的对象都可以作为提供给pRectangular.contains()的rect参数。通过放宽参数类型的限制,我们使方法具有更好的可重用性。
不过,对于上面这个例子,Rectangular接口的getBounds方法返回 Rectangle,你可能会怀疑这么做是否真正值得。换言之,如果我们知道传入过程的对象会在被调用时返回一个Rectangle,为什么不直接传入 Rectangle取代接口类型呢?之所以不这么做,最重要的原因与集合有关。让我们假设有这样一个方法:
static public boolean areAnyOverlapping(Collection rects) {...}
该方法用于检查给定集合中的任意矩形对象是否重叠。在这个方法的内部,当我们用循环依次访问集合中的各个对象时,如果我们不能把对象cast成为 Rectangular之类的接口类型,又如何能够访问对象的矩形区域呢?唯一的选择是把对象 cast成为它特有的类形式(我们知道它有一个方法可以返回矩形),它意味着方法必须事先知道它所操作的对象类型,从而使得方法的重用只限于那几种对象类型。而这正是前面这个措施力图先行避免的问题!
相关文章推荐
- 提高Java代码重用性方法 措施二:把参数类型改成接口
- 提高Java代码重用性的措施三:选择最简单的参数接口类型
- 提高Java代码重用性的措施三:选择最简单的参数接口类型
- 1002 Java形式参数问题-类型名、抽象类、接口
- 为什么 Java ArrayList.toArray(T[]) 方法的参数类型是 T 而不是 E ?
- 利用Javassist获取Java类中的方法参数名、参数类型、方法访问类型
- java方法参数基本类型和方法参数是引用类型的区别
- SpringMVC提高篇(二): 处理器方法支持的方法参数和返回类型
- Java 代码测试接口的方法
- java代码关于匿名内部类和接口的方法使用
- Java方法参数太多怎么办—Part 1—自定义类型
- C#调用VC DLL接口函数参数类型转换方法介绍
- java数据类型、存储以及作为方法参数传递
- [java]类&抽象类&接口分别作为方法参数和返回值
- C#与Java对比学习:类型判断、类与接口继承、代码规范与编码习惯、常量定义
- Java利用反射来获取一个方法的 范型化参数 Vector<Integer>的类型
- java代码中直接问号加参数请求其他接口
- android java 层参数重载glVertexAttribPointer 在es20 C 接口中的处理方法
- JAVA进阶:提高代码可重用性的三个措施
- 黑马程序员--Java基础加强--15.利用反射操作泛型IV【通过反射Method解析泛型方法思路】【通过Method对四种Type子接口类型进行解剖】【使用递归对任意复合泛型类型进行彻底解剖】【个人