Liskov 5.1-5.4

advertisement
Data Abstraction
SWE 619
Software Construction
Last Modified, Spring 2009
Paul Ammann
Data Abstraction



Abstract State (Client State)
Representation State (Internal State)
Methods




Constructors (create objects)
Producers (return immutable object)
Mutators (change state)
Observers (report about state)
2
Motivation






Why data abstraction?
Why hide implementation?
Client code breaks
Malicious or clueless clients don’t
depend on/mess up the state
Maintain properties like rep invariant
Hence, encapsulation
3
IntSet and Poly
Poly
5+3x+8x3, 4x+6x2
{x1, …, xn}
c0+c1x+…
Mutable
Immutable
Students find this
Students find this
easy to implement harder to
implement
but a better approach
IntSet
{4,6} {}, {3,5,9},


4
Specification of IntSet
public class IntSet {
//Overview: IntSets are mutable, unbounded sets of integers
// A typical IntSet is {x1, …, xn}
//constructors
public IntSet()
//Effects: Initializes this to be empty
//methods
public void Insert (int x)
// Modifies: this
// Effects: Adds x to this, i.e., this_post = this + {x}
5
Specification of IntSet (2)
public void remove (int x)
//Modifies: this
//Effects: Removes x from this, i.e., this_post=this –{x}
public boolean isIn (int x)
//Effects: If x is in this, returns true, else returns false
public int size ()
//Effects: Returns the cardinality of this
public int choose () throws EmptyException
// Effects: If this is empty, throws EmptyException else
// returns an arbitrary element of this
6
Remember!




Don’t mention internal state in
constructor or method specifications
Always override toString() (don’t show
the rep)
Client should not see in-between state,
all operations atomic
this_post after execution of procedure
7
Set Notation – figure 5.3
A set is denoted {x1, … xn}
Set union: t = s1 + s2
Set difference: t = s1 – s2
Set intersection: t = s1 & s2
Cardinality |s| denotes the size of set s
Set membership: x in true if x element of set s
Set former: t = { x | p(x)} is the set of all x
such that p(x) is true
These few notions are extremely powerful!
8
Specification of Poly
public class Poly {
// Overview: Polys are immutable polynomials with integer co// -efficients. A typical Poly is c0+c1x+ …
//constructors
public Poly()
// Effects: Initializes this to be the zero polynomial
public Poly (int c, int n) throws NegativeExponentException
// Effects: If n<0 throws NegativeExponentException
// else initializes this to be the Poly cxn
9
Specification of Poly (2)
//methods
public int degree ()
//Effects: Returns the degree of this (the largest exponent
// with non zero coeff. Returns 0 if this is the zero Poly
public int coeff (int d)
//Effects: Returns the coeff of the term of this with exp. d
(what if d > degree? what if d < 0?)
public Poly add (Poly q) throws NullPointerException
//Effects: If q is null throws NPE else
// returns the Poly this + q
public Poly mul (Poly q) throws NPE
//Effects: if q is null throws NPE, else returns this * q
10
Poly in detail





5+3x+8x3 can’t build with the
constructor
Only zero or monomial
NegativeExponentException
No modifies clause: Immutable
No mutators

How does it support add, remove, multiply
etc.?
11
Collections – A Slight Diversion
D
U
P
L
I
C
A
T
E
S
Ordering
N
Y
N
Y
Set
InjectiveList
Bag
Vector,
List
One collection is often implemented with another.
12
Implementation (IntSet)





Rep: Vector  Abstract state: Set
Design decision (els never null)
Use of special value in getIndex,
justified?
Design decision, duplicates in insert
Why is remove as shown?
13
Implementation of IntSet (2)
private Vector els; // the rep
public void insert (int x) {
//Modifies: this (NOT els!)
//Effects: Adds x to the elements of this (NOT els!)
Integer y = new Integer(x);
if (getIndex(y) < 0) els.add(y); }
private int getIndex(Integer x) {
// Effects: If x is in this return index where x appears
// else return -1
for (int i=0; i < els.size(); i++)
if (x.equals(els.get(i))) return i;
return -1; }
14
Implementation of IntSet (3)
public void remove (int x) {
//Modifies: this
//Effects: Remove x from this
int i = getIndex(new Integer(x));
if (i < 0) return;
els.set(i, els.lastElement());
els.remove(els.size() - 1); }
public int choose() {
// Effects: If this empty throw EE else return arbitrary element of this
if (els.size() == 0) throw new EE(“IntSet.choose”);
return ((Integer) els.lastElement()).intValue(); }
15
Implementation of Poly (1)
private int[] trms;
private int deg;
public Poly() {
//Effects: Initializes this to be the zero polynomial
trms = new int[1]; trms[0] = 0; deg = 0; }
public Poly (int c, int n) throws IAE {
//Effects if n < 0 throw IAE else initializes this to cx^n
if (n < 0) throw new IAE(“Poly.constructor”);
if (c ==0) { trms = new int[1]; trms[0] = 0; deg = 0; return}
trms = new int[n+1]; deg = n;
for (int i = 0; i < n; i++) trms[i] = 0;
trms[n] = c; }
private Poly (int n) { trms = new int[n+1] deg = n;}
16
Implementation of Poly (2)
public int degree() {
//Effects: Return degree of this, ie the largest exponent
// with a nonzero coefficient. Returns 0 if this is the zero Poly
return deg;}
public coef (int d) {
// Effects: Returns the coefficient of the term of this whose exp is d
if (d < 0 || d > deg) return 0; else return trms[d];}
// implementations of add, sub, minus, mul
17
Abstraction Function






Abstract state {x1, …, xn}
Representation state?
Vector els = [y0, y1, …, yn]
Representation state is designer’s choice.
Clients don’t see rep (representation state),
only see abstract state
Clients don’t care for rep, as long as it
satisfies properties of abstract state
Implementer can change rep at any time!
18
Abstraction Function (IntSet)


Abstraction function is a mapping from
representation state to abstract state
Abstraction function for IntSet:



AF(c) = c.els[i] | 0  i < c.els.size() }
If duplicates allowed, what should AF(c)
be?
What if null is mapped to {}?
19
AF() for IntSet
Abstract State (IntSet s)
s = {}
s = {1, 2}
s = {1}
els = [null, 5]
els = []
s = {1, 7}
AF()
els = [1, 2]
els = null
els = [“cat”, “hat”]
els = [2, 1]
els = [7, 1, 7]
Representation State (Vector els)
20
Rep Invariant
Rep Invariant is the expression of combined
restrictions on representation
c.els != null
No duplicates in c.els
All entries in c.els are Integers
No null entries
English descriptions are fine!
These are DESIGN DECISIONS.

1.
2.
3.
4.



For example, we COULD allow duplicates...
21
Additional Methods
clone()  wrong in Liskov; we will use Bloch
toString()  Implementation of abstraction function
equals()  non standard wrt Java - understand why
1.
2.
3.



1.
2.
3.
In terms of mutability– different for mutable and immutable
types
Bias towards correctness
Three different things are required:
==
// This checks if same object
equals()
// for immutable only (same abstract state)
similar()
// Mutable (same current abstract state)
// Not implemented in Java
22
equals()

Involves three important criteria: reflexivity,
symmetry, transitivity


Often difficult to implement
For abstract extensions of instantiable
superclasses, impossible to implement!



Details later...
toString  Should match with “typical object”
Trick: Do it backwards - implement toString()
first and then write the abstraction function.
23
Mutable/Immutable Transform

Stack example in Bloch


Transform to an immutable version


Mutable
We should be fine with immutable stacks:
Immutable Stack s = new Stack();
s = s.push(“cat”);
s =s.push(“dog”);
How to tranform:
SWE 619
24
Mutator  Producer
Consider a mutator method in class C:
public void m(T t) or
public S
m(T t)
What do the corresponding immutable methods look
like?
public C m(T t) or
public ??? m(T t)
Second needs to be split into two methods:
Example: pop() vs. pop(), top() in Stack
SWE 619
25
Download