Presentation is loading. Please wait.

Presentation is loading. Please wait.

Abstract Data Types 抽象数据类型 2015/4/12Institute of Computer Software Nanjing University 1.

Similar presentations


Presentation on theme: "Abstract Data Types 抽象数据类型 2015/4/12Institute of Computer Software Nanjing University 1."— Presentation transcript:

1 Abstract Data Types 抽象数据类型 2015/4/12Institute of Computer Software Nanjing University 1

2 提要 软件构造:从面向过程到面向对象 抽象数据类型规约 作为模块化设施的 ADT 语言对 ADT 的支持 其他模块化设施 2015/4/12Institute of Computer Software Nanjing University 2

3 软件构造 程序设计语言是最重要的软件构造工具。 PL 的设计体现软件构造原则。 2015/4/12Institute of Computer Software Nanjing University 3

4 回顾:结构化软件开发 “ 结构化( structured ) ” 开发方法 开发过程侧面 以实现功能为中心 自顶向下,逐步求精 程序设计侧面 小结构: concatenation, selection, and repetition. 大结构:过程抽象,避免全局变量 2015/4/12Institute of Computer Software Nanjing University 4

5 自顶向下( Top-down ) 的功能 设计 12-Apr-15Institute of Computer Software Nanjing University A BDC C1 I1C2 I2 I Topmost functional abstraction Loop Conditional Sequence

6 回顾:结构化软件开发 “ 结构化( structured ) ” 的合理性 管理复杂性的有效手段 分解, 抽象, 层次 Correctness Extendibility? Reusability? 2015/4/12Institute of Computer Software Nanjing University 6

7 从面向过程到面向对象 “ 结构化 ” 的基本思想已经深入人心 但对于复杂、易变、交互性软件系统,以 “ 功 能 ” 为中心的分解方式有局限 完全自顶向下的功能分解? 线性过程式的程序组织? 应变 2015/4/12Institute of Computer Software Nanjing University 7

8 例:考虑一个工资系统 一开始,客户说他的需求很 “ 简单明确 ” : 2015/4/12Institute of Computer Software Nanjing University 8 Employee information Hours worked Produce Paychecks Paychecks

9 例:考虑一个工资系统 这种功能明确的系统确实适合结构化的开发方法:自顶向 下,逐步求精。 你完美地完成了任务。 而后,极有可能,客户会跑过来跟你说: 给我加个统计报表撒 下个月我想一些人发记时工资,一些人发计件工资啊行啊,有人 每月一发,有人每周一发哦 加个个人所得税系统接口 加个图像用户界面,用交互查询 2015/4/12Institute of Computer Software Nanjing University 9

10 从软件构造的角度看 修改变动不可避免 因此问题是如何使其代价较小 修改 “ 局部化 ” 寻找相对稳定的架构,封装变化的部件 2015/4/12Institute of Computer Software Nanjing University 10

11 对程序的一般理解 程序运行:在某个数据体上施以某些操作。 两个要素 操作(功能) Functions [or: Operations, Actions] 客体(对象) Objects [or: Data] 11 Action Object Processor

12 如何导出软件系统的结构? 两条途径: 从操作 / 功能入手 从客体 / 对象入手 形成两种分析设计方法: 基于过程的分解 面向对象的分解 12

13 面向对象的分解好在何处? Reusability: 数据(结构)及其上之操作的整体 复用,而非仅仅复用操作功能; Extendibility, Continuity: 对象更直接对应问题空 间的概念,因而较 “ 功能 ” 更稳定. 13

14 “ 面向对象 ” 的含义(之一) 面向对象的软件构造乃是基于系统所操作之对 象类型(而非系统需实现之功能)来架构系统 的途径。 14

15 The O-O designer’s motto Ask NOT first WHAT the system does: Ask WHAT it does it TO! 15

16 对象刻画 Consider not a single object but a type of objects with similar properties. Define each type of objects not by the objects’ physical representation but by their behavior: the services (FEATURES) they offer to the rest of the world. External, not internal view: ABSTRACT DATA TYPES 16

17 对象刻画问题 The main issue: How to describe program objects (data structures): Completely Unambiguously Without overspecifying? (Remember information hiding) 2015/4/12Institute of Computer Software Nanjing University 17

18 A stack, concrete object 18 count representation (array_up) capacity representation [count] := x free (array_down) 1 representation n new (linked) item previous item previous “Push” operation: count := count + 1 representation [free] := x “Push” operation: free := free - 1 new (n) n.item := x “Push” operation: n.previous := last head := n

19 A stack, concrete object 19 count representation (array_up) capacity representation [count] := x free (array_down) 1 representation n new (linked) item previous item previous “Push” operation: count := count + 1 representation [free] := x “Push” operation: free := free - 1 new (n) n.item := x “Push” operation: n.previous := last head := n

20 抽象数据类型 一种数学的刻画方式 “ 类型 ” ? -- (Data type, 简称 Type) 值 操作函数 规律公理 2015/4/12Institute of Computer Software Nanjing University 20

21 Stack: An abstract data type Types: STACK [G] -- G: Formal generic parameter Functions (Operations): put: STACK [G]  G  STACK [G] remove: STACK [G]  STACK [G] item: STACK [G]  G empty: STACK [G]  BOOLEAN new: STACK [G] 21

22 Using functions to model operations 22 put,= () sxs’

23 Reminder: Partial functions A partial function, identified here by , is a function that may not be defined for all possible arguments. Example from elementary mathematics: inverse:   , such that inverse (x) = 1 / x 23

24 The STACK ADT (cont’d) Preconditions: remove (s: STACK [G]) require not empty (s) item (s: STACK [G]) require not empty (s) Axioms: For all x: G, s: STACK [G] item (put (s, x)) = x remove (put (s, x)) = s empty (new) (or: empty (new) = True) not empty (put (s, x)) (or: empty (put (s, x)) = False) 24 put (,) = sxs’

25 Formal stack expressions value = item (remove (put (remove (put (put (remove (put (put (put (new, x8), x7), x6)), item (remove (put (put (new, x5), x4)))), x2)), x1))) 25

26 Expressed differently s1 = new s2 = put (put (put (s1, x8), x7), x6) s3 = remove (s2) s4 = new s5 = put (put (s4, x5), x4) s6 = remove (s5) y1 = item (s6) s7 = put (s3, y1) s8 = put (s7, x2) s9 = remove (s8) s10 = put (s9, x1) s11 = remove (s10) value = item (s11) 26 value = item (remove (put (remove (put (put (remove (put (put (put (new, x8), x7), x6)), item (remove (put (put (new, x5), x4)))), x2)), x1)))

27 An operational view of the expression value = item (remove (put (remove (put (put (remove (put (put (put (new, x8), x7), x6)), item (remove (put (put (new, x5), x4)))), x2)), x1))) 27 x8 x7 x6 x8 x7 s2s3 (empty) s1 x5 x4 s5 (empty) s4 x5 s6 y1 x8 x7 x5 s7 (s9, s11) x8 x7 x5 s8 x2 x8 x7 x5 s10 x1

28 Expression reduction (1/10) value = item ( remove ( put ( remove ( put ( remove ( put (put (put (new, x8), x7), x6) ), item ( remove ( put (put (new, x5), x4) ), x2) ), x1) ) 28 x7 x8 x6 x5 x4 Stack 1Stack 2

29 Expression reduction (2/10) value = item ( remove ( put ( remove ( put ( remove ( put (put (put (new, x8), x7), x6) ), item ( remove ( put (put (new, x5), x4) ), x2) ), x1) ) 29 x7 put remove x8 x7 x8 x7 x8 x6 x5 x4 Stack 1Stack 2

30 ADT 函数分类 一个 ADT T 中可有三种函数 : Creators: OTHER  T e.g. new Queries: T ...  OTHERe.g. item, empty Commands: T ...  T e.g. put, remove Note : Mutable vs. Immutable 2015/4/12Institute of Computer Software Nanjing University 30

31 ADT 规约质量? 到底要描述多少特性才足够? 相对什么而言 完全? 数学的完全? 会不会描述的太多 “ 言多必失 ” ? 一致性? 2015/4/12Institute of Computer Software Nanjing University 31

32 Sufficient Completeness 一个类型 T 的 ADT 规约是 sufficiently complete 当且仅当 对于任何 well-formed 的表达式 e 均可依据该 ADT 的公理 S1 判定 e 是否 correct. S2 若 e 为查询表达式且 correct, 则 e 的值可不用任何 T 类型的值就可表达。 (一般而言不可判定) 2015/4/12Institute of Computer Software Nanjing University 32

33 Consistency An ADT specification is consistent if and only if, for any well-formed query expression e, the axioms make it possible to infer at most one value for e. (一般而言不可判定) 2015/4/12Institute of Computer Software Nanjing University 33

34 Stack: An abstract data type Types: STACK [G] -- G: Formal generic parameter Functions (Operations): put: STACK [G]  G  STACK [G] remove: STACK [G]  STACK [G] item: STACK [G]  G empty: STACK [G]  BOOLEAN new: STACK [G] 34

35 The STACK ADT (cont’d) Preconditions: remove (s: STACK [G]) require not empty (s) item (s: STACK [G]) require not empty (s) Axioms: For all x: G, s: STACK [G] item (put (s, x)) = x remove (put (s, x)) = s empty (new) (or: empty (new) = True) not empty (put (s, x)) (or: empty (put (s, x)) = False) 35 put (,) = sxs’

36 证明 证明上述 ADT 的 sufficient completeness 判定任何一个 well-formed 的栈表达式 e 的 correct 与否 若 e 的确 correct, 求 empty(e) 和 item(e) 的值(以不 包含栈值的表达式表示) 2015/4/12Institute of Computer Software Nanjing University 36

37 基本思路 对表达式长度(嵌套层数即括号对数)进行归 纳 操作性解释: 影响 correctness 的关键是栈中元素多少 查询操作不改变栈状态 仅 new put remove 改变 Empty(put...) item(put...) 均可求值 故消解 remove 即可 2015/4/12Institute of Computer Software Nanjing University 37

38 Weight The weight of a well-formed stack expression not involving item or empty is defined inductively as follows: W(new) = 0. W(put (s, x)) = W(s) + 1 W(remove (s)) = W(s) /4/12Institute of Computer Software Nanjing University 38

39 Weight Consistency rule : A well-formed stack expression e, involving neither item nor empty, is correct if and only if its weight is non-negative, and any subexpression of e is (recursively) correct. Zero Weight rule: Let e be a well-formed and correct stack expression not involving item or empty. Then empty (e) is true if and only if e has weight /4/12Institute of Computer Software Nanjing University 39

40 2015/4/12Institute of Computer Software Nanjing University 40 以归纳法证明上述两规则: e 是 well-formed 的 不包含 empty 和 item 1. e 是 correct 的 W(e) ≥ 0 ∧ e 中的子表达式 correct 2. 若 e 是 correct 的, empty(e) W(e)=0 嵌套层数为 0 :必为 new ,上述两规则显然成立(当然我 们也可以验证为 1 的情况) 假设对于嵌套层数不超过 n 的表达式上述两规则均成立, 现证明对于嵌套层数为 n+1 时它们成立 考虑 e 的最外层函数 必为 put 或 remove 若 e = put(s, x),......

41 2015/4/12Institute of Computer Software Nanjing University 若 e = remove(s), 1=> e is correct, s is correct and not empty(s), W(s)>0 W(e)=W(s)-1 ≥0 1<= 2 W(s)>0, s 至少有一个 put ,设其最外的 put 为 put(s ’, xexp), 在 e 中它的外面必为 remove... remove( put ( s ’, xexp ) )... e 变成 e ’ 层数减 2 empty 值不变 规则 2 成立 Correct 的无 empty 和 item 的表达式可消去 remove

42 2015/4/12Institute of Computer Software Nanjing University 42 利用这两个规则证明 sufficient Completeness. 再对嵌套层 数进行归纳 e = f(s) S 嵌套层数为 0 必为 new, empty(s)= TRUE, item(s) 不 correct 假设 s 层数不超过 n 时 f(s) 的 correctness 可判定,若 correct 则 empty(s) 和 item(s) 的值可求 现证明 层数为 n+1 亦如是 考虑 s 的子表达式 u, 若 u 最外层为 empty 或 item ,因 u 嵌套 层数不超过 n ,它的 correctness 可判定,若不 correct, 则 s 不 corrct, 若 u 是 correct 的,则可求值;不断对这样的 u 求 值 最终 消解 empty 和 item, 消解 remove, 仅剩 put 和 new , 若外层为 new 上面已讨论, 若 s=put(s ’, x), 则 empty(s) 正 确且等于 FALSE , item(s) 正确且等于 x

43 ADT 与软件开发 ADT 为软件模块分解提供了理论基础: 2015/4/12Institute of Computer Software Nanjing University 43

44 ADT and software architecture Identify every module with an implementation of an abstract data type, i.e. the description of a set of objects with a common interface. The interface is defined by a set of operations (implementing the functions of the ADT) constrained by abstract properties (the axioms and preconditions). The module consists of a representation for the abstract data type and an implementation for each of the operations. Auxiliary operations may also be included. 44

45 Implementing an ADT Three components: (E1)The ADT’s specification: functions, axioms, preconditions. (Example: stacks.) (E2)Some representation choice. (Example:.) (E3)A set of subprograms (routines) and attributes, each implementing one of the functions of the ADT specification (E1) in terms of the chosen representation (E2). (Example: routines put, remove, item, empty, new.) 45

46 A choice of stack representation 46 count representation (array_up) capacity “Push” operation: count := count + 1 representation [count] := x

47 信息隐蔽原则 47 Secret part: Choice of representation (E2) Implementation of functions by features (E3) ADT specification (E1) Public part:

48 “ 面向对象 ” 的含义(进一步) 面向对象的软件构造乃是将系统构造为抽象数 据类型实现(可能是部分实现)的结构化组合。 这个 “ 抽象数据类型的实现 ” 就是类( class ) 48

49 从程序设计语言的角度看 应当通过恰当的程序设计语言支撑上述软件构 造思想。 关键在: 抽象机制:在过程抽象的基础上,还需要数据抽象 封装机制:实现信息隐蔽 2015/4/12Institute of Computer Software Nanjing University 49

50 何谓 “ 抽象 ” An abstraction is a view or representation of an entity that includes only the most significant attributes Nearly all programming languages support process abstraction with subprograms Nearly all programming languages designed since 1980 support data abstraction

51 数据抽象 程序设计语言对抽象数据类型的支持是指允许 用户自定义具有如下特征的数据类型: 1. 模块封装: The representation of, and operations on, objects of the type are defined in a single syntactic unit 2. 信息隐蔽: The representation of objects of the type is hidden from the program units that use these objects, so the only operations possible are those provided in the type's definition

52 数据抽象的优势 模块封装的优势 Program organization, modifiability (everything associated with a data structure is together), and separate compilation 信息隐蔽的优势 Reliability--by hiding the data representations, user code cannot directly access objects of the type or depend on the representation, allowing the representation to be changed without affecting user code

53 要支持 ADT ,需要 A syntactic unit in which to encapsulate the type definition A method of making type names and subprogram headers visible to clients, while hiding actual definitions Some primitive operations must be built into the language processor

54 Design Issues Can abstract types be parameterized? What access controls are provided?

55 Language Examples: Ada The encapsulation construct is called a package Specification package (the interface) Body package (implementation of the entities named in the specification) Information Hiding The spec package has two parts, public and private The name of the abstract type appears in the public part of the specification package. This part may also include representations of unhidden types The representation of the abstract type appears in a part of the specification called the private part More restricted form with limited private types Private types have built-in operations for assignment and comparison Limited private types have NO built-in operations

56 Language Examples: Ada (continued) Reasons for the public/private spec package: 1. The compiler must be able to see the representation after seeing only the spec package (it cannot see the body package) 2. Clients must see the type name, but not the representation (they also cannot see the private part)

57 Language Examples: Ada (continued) Having part of the implementation details (the representation) in the spec package and part (the method bodies) in the body package is not good One solution: make all ADTs pointers Problems with this: 1. Difficulties with pointers 2. Object comparisons 3. Control of object allocation is lost

58 An Example in Ada package Stack_Pack is type stack_type is limited private; max_size: constant := 100; function empty(stk: in stack_type) return Boolean; procedure push(stk: in out stack_type; elem:in Integer); procedure pop(stk: in out stack_type); function top(stk: in stack_type) return Integer; private -- hidden from clients type list_type is array (1..max_size) of Integer; type stack_type is record list: list_type; topsub: Integer range 0..max_size) := 0; end record; end Stack_Pack

59 Language Examples: C++ Based on C struct type and Simula 67 classes The class is the encapsulation device All of the class instances of a class share a single copy of the member functions Each instance of a class has its own copy of the class data members Instances can be static, stack dynamic, or heap dynamic

60 Language Examples: C++ (continued) Information Hiding Private clause for hidden entities Public clause for interface entities Protected clause for inheritance (Chapter 12)

61 Language Examples: C++ (continued) Constructors: Functions to initialize the data members of instances (they do not create the objects) May also allocate storage if part of the object is heap-dynamic Can include parameters to provide parameterization of the objects Implicitly called when an instance is created Can be explicitly called Name is the same as the class name

62 Language Examples: C++ (continued) Destructors Functions to cleanup after an instance is destroyed; usually just to reclaim heap storage Implicitly called when the object’s lifetime ends Can be explicitly called Name is the class name, preceded by a tilde (~)

63 An Example in C++ class stack { private: int *stackPtr, maxLen, topPtr; public: stack() { // a constructor stackPtr = new int [100]; maxLen = 99; topPtr = -1; }; ~stack () {delete [] stackPtr;}; void push (int num) {…}; void pop () {…}; int top () {…}; int empty () {…}; } 鼓励声明和 实现分离 C++ 也存在声 明中有私有 表示的问题, 如何弥补?

64 Evaluation of ADTs in C++ and Ada C++ support for ADTs is similar to expressive power of Ada Both provide effective mechanisms for encapsulation and information hiding Ada packages are more general encapsulations; classes are types

65 Language Examples: C++ (continued) Friend functions or classes - to provide access to private members to some unrelated units or functions Necessary in C++

66 Language Examples: Java Similar to C++, except: All user-defined types are classes All objects are allocated from the heap and accessed through reference variables Individual entities in classes have access control modifiers (private or public), rather than clauses Java has a second scoping mechanism, package scope, which can be used in place of friends All entities in all classes in a package that do not have access control modifiers are visible throughout the package

67 An Example in Java class StackClass { private int [] stackRef; private int [] maxLen, topIndex; public StackClass() { // a constructor stackRef = new int [100]; maxLen = 99; topPtr = -1; }; public void push (int num) {…}; public void pop () {…}; public int top () {…}; public boolean empty () {…}; }

68 Language Examples: C# Based on C++ and Java Adds two access modifiers, internal and protected internal All class instances are heap dynamic Default constructors are available for all classes Garbage collection is used for most heap objects, so destructors are rarely used struct s are lightweight classes that do not support inheritance

69 Language Examples: C# (continued) Common solution to need for access to data members: accessor methods (getter and setter) C# provides properties as a way of implementing getters and setters without requiring explicit method calls

70 C# Property Example public class Weather { public int DegreeDays { //** DegreeDays is a property get {return degreeDays;} set { if(value 30) Console.WriteLine( " Value is out of range: {0} ", value); else degreeDays = value;} } private int degreeDays;... }... Weather w = new Weather(); int degreeDaysToday, oldDegreeDays;... w.DegreeDays = degreeDaysToday;... oldDegreeDays = w.DegreeDays;

71 Abstract Data Types in Ruby Encapsulation construct is the class Local variables have “normal” names Instance variable names begin with “at” signs ) Class variable names begin with two “at” signs ( ) Instance methods have the syntax of Ruby functions ( def … end ) Constructors are named initialize (only one per class) Class members can be marked private or public, with public being the default Classes are dynamic

72 Abstract Data Types in Ruby (continued) class StackClass { def = = = -1 end def push(number) … end def pop … end def top … end def empty … end end

73 Parameterized Abstract Data Types Parameterized ADTs allow designing an ADT that can store any type elements (among other things) Also known as generic classes C++, Ada, Java 5.0, and C# 2005 provide support for parameterized ADTs

74 Parameterized ADTs in Ada Ada Generic Packages Make the stack type more flexible by making the element type and the size of the stack generic generic Max_Size: Positive; type Elem_Type is private; package Generic_Stack is Type Stack_Type is limited private; function Top(Stk: in out StackType) return Elem_type; … end Generic_Stack; Package Integer_Stack is new Generic_Stack(100,Integer); Package Float_Stack is new Generic_Stack(100,Float);

75 Parameterized ADTs in C++ Classes can be somewhat generic by writing parameterized constructor functions class stack { … stack (int size) { stk_ptr = new int [size]; max_len = size - 1; top = -1; }; … } stack stk(100);

76 Parameterized ADTs in C++ (continued) The stack element type can be parameterized by making the class a templated class template class stack { private: Type *stackPtr; const int maxLen; int topPtr; public: stack() { stackPtr = new Type[100]; maxLen = 99; topPtr = -1; } … }

77 Parameterized Classes in Java 5.0 Generic parameters must be classes Most common generic types are the collection types, such as LinkedList and ArrayList Eliminate the need to cast objects that are removed Eliminate the problem of having multiple types in a structure

78 Parameterized Classes in C# 2005 Similar to those of Java 5.0 Elements of parameterized structures can be accessed through indexing

79 Encapsulation Constructs Large programs have two special needs: Some means of organization, other than simply division into subprograms Some means of partial compilation (compilation units that are smaller than the whole program) Obvious solution: a grouping of subprograms that are logically related into a unit that can be separately compiled (compilation units) Such collections are called encapsulation

80 Nested Subprograms Organizing programs by nesting subprogram definitions inside the logically larger subprograms that use them Nested subprograms are supported in Ada, Fortran 95, Python, and Ruby

81 Encapsulation in C Files containing one or more subprograms can be independently compiled The interface is placed in a header file Problem: the linker does not check types between a header and associated implementation #include preprocessor specification – used to include header files in applications

82 Encapsulation in C++ Similar to C Addition of friend functions that have access to private members of the friend class

83 Ada Packages Ada specification packages can include any number of data and subprogram declarations Ada packages can be compiled separately A package’s specification and body parts can be compiled separately

84 C# Assemblies A collection of files that appear to be a single dynamic link library or executable Each file contains a module that can be separately compiled A DLL is a collection of classes and methods that are individually linked to an executing program C# has an access modifier called internal ; an internal member of a class is visible to all classes in the assembly in which it appears

85 Naming Encapsulations Large programs define many global names; need a way to divide into logical groupings A naming encapsulation is used to create a new scope for names C++ Namespaces Can place each library in its own namespace and qualify names used outside with the namespace C# also includes namespaces

86 Naming Encapsulations (continued) Java Packages Packages can contain more than one class definition; classes in a package are partial friends Clients of a package can use fully qualified name or use the import declaration Ada Packages Packages are defined in hierarchies which correspond to file hierarchies Visibility from a program unit is gained with the with clause

87 Naming Encapsulations (continued) Ruby classes are name encapsulations, but Ruby also has modules Typically encapsulate collections of constants and methods Modules cannot be instantiated or subclassed, and they cannot define variables Methods defined in a module must include the module’s name Access to the contents of a module is requested with the require method

88 小结 The concept of ADTs and their use in program design was a milestone in the development of languages Two primary features of ADTs are the packaging of data with their associated operations and information hiding Ada provides packages that simulate ADTs C++ data abstraction is provided by classes Java’s data abstraction is similar to C++ Ada, C++, Java 5.0, and C# 2005 support parameterized ADTs C++, C#, Java, Ada, and Ruby provide naming encapsulations


Download ppt "Abstract Data Types 抽象数据类型 2015/4/12Institute of Computer Software Nanjing University 1."

Similar presentations


Ads by Google