抽象数据类型(ADT)和面向对象编程(OOP)3.3 抽象数据类型

抽象类型的新颖性和不同之处在于对操作的关注类型的用户不需要担心它的值如何实际存储

类型无论是内置的还是用户定义的,都可以分类为可变或不可变

可变类型的对象可以被改变

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