1.抽象性和用户定义类型
用户定义类型
除了编程语言所提供的基本数据类型和对象数据类型,程序员可以定义自己的数据类型。
数据抽象性
数据抽象:由一组操作所刻画的数据类型。(不关心数据的具体表示)。只需设计/使用操作。
抽象类型是被他的操作所定义的
和内部如何实现操作无关
2.数据类型分类和运算
可变和不可变类型
可变类型的对象:提供了可以改变其内部数据值的操作。
不可变类型:其操作不可改变内部值,而是构造新的对象。
有时候一种类型会提供两种形式:String和StringBuilder
抽象数据类型操作的分类
构造器(Creator)从无到有(可以从其他类型构造)。
生产器(Producers)从旧到新,从原来旧的对象生成一个新的对象。
观察器(Observers)
变值器(Mutators)改变已有对象属性
运算的签名
构造器:可能实现为构造函数或静态函数(后者称为工厂方法)
变值器:变值器通常返回void,反过来如果返回void,这意味着他改变了对象的某些内部状态。
变值器也可能返回非空类型,(比如返回布尔值看是否真的改变)
3.抽象数据类型的例子
int和String没有变值器,他们是不可变的。
4.设计一个抽象数据类型
设计简洁、一致的原则。
足以支持客户端对数据所做的所有操作需要
通用和具体不应该混合使用。
5.表示独立性
表示独立性
client不考虑内部实现,ADT内部变化不影响客户端。
6.测试一个抽象数据类型
怎么测试ADT
测试creators,producers,mutators,调用obsevers来查看
测试obsevers,调用前三者来改变对象,看结果是否正确。
风险:被依赖的其他方法可能有错误。
7.不变量
ADT的不变量
ADT需要始终保持其不变量:程序在任何时候总为true的性质。
保持程序的正确性,容易发现错误。
采用防御式拷贝
使用不变数据类型
8.表示不变性和抽象函数
值的两个空间
R:表示值构成的空间,使用者看到和实现的值。
A:抽象值构成的空间,调用者看到和使用的值
R和A之间的映射
满射。
抽象函数AF
R和A之间映射关系的函数,
表示不变性RI
描述了什么是合法的表示值,是所有表示值的子集
可以进行是否判断
RI和AF文档
注释
随时检查RI是否满足
在所有可能改变表示的地方都要检查。
9.有益的可变性
有益的可变性
这种可变性只是改变了R值,并没有改变A值,对调用者来说是不可变的。
通过牺牲可变性来换取效率和性能。
(在内部改变R值,不改变A值)
10.AF,RI文档和表示泄露的安全性
AF和Ri文档
在代码中用注释形式记录AF和RI
RI:rep中的所有fields何为有效。
AF:如何解释每一个R值。
表示泄露安全声明文档
给出理由,证明代码未对外泄露其内部表示
使用了private,类型不可变等等。
总结:ADT规约讨论了什么
只能用客户端可见的方式来撰写
如果规约中提及值,则只能是抽象空间的值。不能提及任何R空间中的值
因此AF和RI在代码中以注释写出。
11.ADT不变量取代前置条件