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

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

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

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

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

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

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

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

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

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

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’

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

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)))

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

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

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

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

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

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

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

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

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’

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) - 1 2015/4/12Institute of Computer Software Nanjing University 38

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 0. 2015/4/12Institute of Computer Software Nanjing University 39

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),......

2015/4/12Institute of Computer Software Nanjing University 41....... 若 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

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

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

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

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

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

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

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

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)

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

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

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

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

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

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 (~)

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++ 也存在声 明中有私有 表示的问题， 如何弥补？

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

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

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

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 () {…}; }

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

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

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;

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

Abstract Data Types in Ruby (continued) class StackClass { def initialize @stackRef = Array.new @maxLen = 100 @topIndex = -1 end def push(number) … end def pop … end def top … end def empty … end end

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

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);

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);

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; } … }

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

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

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

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

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

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

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

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

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

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

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

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

Similar presentations