数据抽象
数据抽象:指一组操作刻画的数据类型,例如:
Number:一种可以进行加法和乘法操作的数据类型。
String:一种可以进行连接和取子串的数据类型。
对我们传统的数据类型来说,我们往往会关注数据的具体表示,而抽象数据类型更关注作用于数据上的操作,程序员和客户端不需要关注数据具体是如何实现的,只需要设计/使用即可。
例如,我们可以使用如下操作来定义一个列表:
List list1 = new ArrayList();
List list2 = new LinkedList();
在这里,List就是一个抽象的数据类型,我们只需要知道我们使用的list1和list2实现了List接口中定义的操作,而不需要关心list是如何具体实现的。
区分类型与操作
可变类型与不可变类型
可变数据类型:提供了可以改变其内部值的操作。
不可变数据类型:其操作不能改变内部值,而是构造新的对象。
例如,Date类是一个可变数据类型,因为它支持setter方法,例如:
Date d1 = new Date();
d1.setMonth(1);
而String类是一个不可变数据类型,对String的操作不会改变其内部值,而是构造新的对象。但很多类型都提供两种形式,例如Java为String提供了一个可变数据类型版本:StringBuilder。
抽象数据类型的操作的分类
构造器(Creators)
构造器将会创建这个类型的一个新对象,构造器可能会以一个对象作为参数,但是这个对象一定不是相同类型的对象。构造器是一个从无到有的过程,在Java中的构造方法和静态函数就是一个构造器的例子。实现为静态方法的构造器通常称为工厂方法。
生产器(Producers)
生产器将会基于这个类型的旧对象生成同一类型的新对象。生产器是一个从有到新的过程,在Java中,String类的concat()方法就是一个生产器,它接受两个String对象作为参数,返回两个String对象连接后的结果。
观察器(Observers )
观察器基于这个对象返回一个不同类型的对象。例如List类中的size()方法就是一个观察器,各种类的getter方法也是观察器。
变值器(Mutators)
变值器将会改变对象的属性。例如List类中的add()方法,以及各种类中的setter方法也是变值器,通常返回为void,有时也返回其他数据类型。一般一个函数返回void,那么它一定是变值器。
表示独立性
不变量
不变量指的是程序在任何时候总保持为true的性质,例如不可变性就是一个ADT的不变量。不变量只由ADT来负责,与客户端无关。
为什么需要不变量
当ADT维护不变量时,能够保证程序的正确性,不易发生错误。例如你保证了String在使用时不会发生改变,在调试使用String或是试图为另一个使用String的ADT建立不变量的代码时,可以排除这种可能性。如果没有这个不变量,那么在所有使用String的地方,都要检查其是否改变了。