抽象类型的新颖性和不同之处在于对操作的关注:类型的用户不需要担心它的值如何实际存储
类型无论是内置的还是用户定义的,都可以分类为可变或不可变
可变类型的对象可以被改变
String是不可变的,因为它的操作创建了新的String对象而不是改变现有的对象
有时一种类型将以两种形式提供,一种可变形式和一种不可变形式。 例如,StringBuilder是String的一个可变版本(不可互换)
Creators (构造器)创建该类型的新对象。Creators可以将对象作为参数,但不是正在构建的类型的对象。
Producers(生产器)从该类型的旧对象创建新对象。 - 例如,String的concat()方法是一个生产者:它需要两个字符串并产生一个代表它们串联的新字符串。
Observers(观察器)获取抽象类型的对象并返回不同类型的对象,例,List.size(),返回的是int值
Mutators(变值器)改变对象属性的方法,List.add(),通过添加元素,改变list
String.concat() 是producer
concat: String × String → String
List.size() 是observer
size: List → int
String.regionMatches 是 observer
regionMatches: String × boolean × int × String × int × int → boolean
Creator:可能实现为构造函数或静态函数
实现为静态方法的创建者通常称为工厂方法,String.valueOf()方法是作为工厂方法实现的创建者的其他示例
Mutator:通常返回void(如果返回值为void则意味着必然改变了对象的某些内部状态)
并不一定返回void List.add()返回boolean类型
java的图形界面用户工具包 Conponent.add()返回对象本身
List(可变)
int(不可变)
String(不可变)
设计抽象数据类型:基本信息不应该非常难以获得
表示独立性
一个好的抽象数据类型应该是独立于表示的,这意味着抽象类型的使用与其表示形式(用于实现它的实际数据结构或数据字段)无关,因此表示形式的变化对抽象类型本身之外的代码没有影响。
例如:List提供的操作与List是以LinkedList还是以数组(arraylist)表示无关。除非通过前置条件和后置条件充分指定了操作,否则您将无法更改ADT的表示形式,以便客户知道要依赖哪些内容,并且知道可以安全更改的内容。
一个好的抽象数据类型的最重要的属性是它保留了它自己的不变量(ADT负责确保自己的不变量保持不变,与客户端无关)
对于程序的每种可能的运行时状态而言,invariant都是程序的属性,它总是正确的。 - 不变性是一个至关重要的不变量:一旦创建,一个不可变对象在整个生命周期中应始终表示相同的值。
由公共方法调用维护 - 在方法执行期间可能暂时失效
为何保持不变量:推理代码更容易,如果已知某个不会改变,在debug时就不用考虑它,为另一个ADT创建一个不变也可以用它。如果只是用户保证不改变,还是要检查每一个用到该部分的代码
一定是满射,单射双射不一定。R:rep value A:abstract value 表示空间 抽象空间
AF:一个抽象函数将rep值映射到它们表示的抽象值 AF : R → A
表示不变量RI:RI : R → boolean a rep value r , RI(r) 是 true 当且仅当r 在 AF上有对应的A
抽象值空间本身并不决定AF RI
构造器生产器在创建对象时确保不变量为true,变值器观察器运行时保持不变性
三个标准检查ADT是否保持不变量:
①由creators producers创建②observers mutataors保持③没有表示泄露发生
表示泄露的安全声明:给出证明表示代码并未对外泄露其内部表示
以注释的形式写RI AF,不能写在Javadoc中,防止被外部看到,破坏表示独立性
原文地址:https://www.cnblogs.com/xgl122/p/9216708.html