第7课P186讲到:借助这两种抽象机制(参数抽象和规范抽象),我们可以实现五类基本抽象:过程抽象、数据抽象、迭代抽象、类型层级、多态抽象。
还不是很明白这两种抽象机制与五类基本抽象的关系。比如:迭代抽象如何体现了参数抽象和规范抽象。
第7课P186讲到:借助这两种抽象机制(参数抽象和规范抽象),我们可以实现五类基本抽象:过程抽象、数据抽象、迭代抽象、类型层级、多态抽象。
还不是很明白这两种抽象机制与五类基本抽象的关系。比如:迭代抽象如何体现了参数抽象和规范抽象。
过程抽象赋予程序员自定义函数或运算的能力。参数抽象和规范抽象在其中的体现应该是明显的,以开方函数sqrt(double number)为例:
number可以是任何一个非负double型变量,这是参数抽象;调用者不必关心sqrt的实现,只根据它的规范便确信sqrt(a)将保证返回a的一个平方根,这是规范抽象。
数据抽象赋予程序员自定义数据类型的能力。参数抽象和规范抽象在其中的体现与过程抽象是类似的。类型层级和多态抽象则是在数据抽象的基础上融入了类族和多态的因素。
迭代抽象赋予程序员自定义循环的能力。在没有迭代抽象时,程序员如果需要遍历一个容器,需要关注不少的细节:如何获取容器的元素?何处是起点?何处是终点?遍历的方式(顺序、倒序、随机、跳跃)?这不仅增加了客户的负担,也限制了容器今后的变化(担心影响到客户)。
以Java的Iterator为例:
public interface Iterator<E>{
boolean hasNext(); // Returns true if the iteration has more elements.
E next(); // Returns the next element in the iteration.
void remove(); // Removes from the underlying collection the last element
}
要遍历一个容器,只需要获取它的一个Iterator对象即可。在这里,Iterator便是一个规范抽象,其规范体现在hasNext、next和remove的文档描述上。
更简单地,只要容器实现了Iterable接口,便可采用for-each循环:
for (ElementType element : elements) process(element);
在这里,连hasNext和next的调用都被隐去了,可以认为抽象得到了进一步的提升,此时迭代已经上升到了语言层面(借鉴了C#语法)。
更明白了,谢谢!
关于迭代抽象,我最早习惯C的for(int i; i < n; i++),但有时不小心就会出现死循环,而foreach不存在死循环问题,所以逐渐开始用后者了。这也印证了抽象层次越高越普适越可靠。
Java在开始引入foreach时遭到一些非议,认为是无多大用处的语法糖。不过只要能让代码更简洁、可读性更高、更不容易出bug,便是语法糖又何妨?何况这样的用法的确提高了抽象的层次,让同样的表达适用于更多的underlying容器(甚至包括最基本的数组),对底层变化的适应力更强。
You must log in to post.