Title: Type Abstraction
1Type Abstraction
2Liskov Substitution Principle
- In any client code, if the supertype object is
substituted by a subtype object, the clients
expectations will still be satisfied. - Everyone learns this in intro OO courses, but
this is a lot harder than it looks.
3Why do we subtype?
- Extended Behavior
- Standard Is-A Relationships
- Multiple implementations
- SparsePoly, DensePoly
- Different implementations
- Same specifications
- All supertype behavior must be supported
- No extra stuff!
4Extended behavior
- Extended Behavior
- Specialize the behavior of supertype
- Classic IS A relationship
- Usually has additional rep.
CAR
Vehicle
Constraint View for contracts
Object View for rep
5Conflict in two goals?
Poly
Poly
SparsePoly
LogPoly
DensePoly
SparsePoly
DensePoly
LogPoly Extends the behavior of Poly by keeping
track of how many times it was accessed by the
calling code. It has additional rep (a log of
accesses)
LogPoly
6Dispatching
- Object x new Object2
- x0 new String(abc)
- x1 new Integer(1)
- for(int i0 iltx.lengthi)
- System.out.println(xi.toString())
- Compiler does not complain
- Which toString() method is called?
Object.toString(), String.toString() or
Integer.toString()? - At run time, best fit code is called.
7MaxIntSet Example (Fig 7.5)
- public class MaxIntSet extends IntSet
- private int biggest // biggest element of set
if not empty - public MaxIntSet super () //Why call super()
??? - public void insert (int x)
- if (size() 0 x gt biggest) biggest x
- super.insert(x)
- public int max () throws EmptyException
- if (size() 0) throw new EmptyException
(MaxIS.max) - return biggest
8MaxIntSet.remove()
- public void remove (int x)
- super.remove(x)
- if (size()0 x ltbiggest) return
- Iterator g elements()
- biggest ((Integer) g.next()).intValue()
- while (g.hasNext()
- int z ((Integer) g.next()).intValue()
- if (zgtbiggest) biggest z
-
- Need to call supertypes remove functionality.
(private rep!) - Must maintain subtypes rep invariant
9MaxIntSet Abstract State
- // Overview MaxIntSet is a subtype of IntSet
with an additional - // method, max, to determine the maximum element
of the set -
- Two possible abstract states
- x1, x2, ... xN - same as IntSet
- ltbiggest, x1, x2, ... xNgt - visible abstract
state - Which one to choose?
- Design decision - either is possible
- Second may seem more natural, but there are
significant advantages to the first. - We will revisit this via Bloch later in the
semester.
10MaxIntSet.repOk()
- public boolean repOk()
- if (!super.repOk()) return false
- if (size() 0) return true
- boolean found false
- Iterator g elements()
- while(g.hasNext())
- int z ((Integer)g.next()).intValue()
- if (zgtbiggest) return false
- if (zbiggest) found true
- return found
11repOk() and Dynamic Dispatching
- public class IntSet
- public void insert(int x) ... repOk()
- public void remove(int x) ... repOk() //
where to? - public boolean repOk() ...
-
- public class MaxIntSet extends IntSet
- public void insert(int x) ...
super.insert(x) repOk() - public void remove(int x) super.remove(x)
... repOk() - public boolean repOk() super.repOk() ...
-
- MaxIntSet s 3, 5 s.remove(5) // repOk()????
12Meaning of subtypes
- Subtypes behavior must support supertype behavior
(SP) - In particular following three properties
- Signature Rule
- Methods Rule
- Properties Rule
13Signature Rule
- Subtypes must have all methods of supertype
- Signatures of methods must be compatible with
supertype signature - Return types identical Covariant after Java 1.5
- Guaranteed by Java compiler
- Caution Overriding vs. overloading
- public boolean equals(Foo foo) ...
- public boolean equals(Object foo) ...
- Exceptions
- Signature Rule allows Subtype to throw fewer
- But methods rule must be satisfied
14Methods Rule
- When object belongs to subtype, subtype method is
called - We must still be able to reason about these
methods using supertype specs - Suppose SortedIntSet extends IntSet
- IntSet x new IntSet()
- IntSet y new SortedIntSet()
- x.insert(3) //What is this_post?
- y.insert(3) //What is this_post?
15Methods Rule
- Cannot take away methods!
- Subtype API should atleast be equal or greater
than supertype API - Must maintain the contract!
- Precondition rule What can a subclass do with
preconditions in supertype spec? - Post condition rule What can a subclass do with
postconditions in supertype spec?
16Precondition rule
- Subtype is allowed to weaken the precondition!
- Formally
- pre_super - pre_sub
- Super //Requires x gt 5
- Case 1 Sub //Requires x gt 6
- Case 2 Sub // Requires x gt 4
- xgt5 ? xgt4? Which is weaker?
- xgt5 ? xgt6?
- Not checked by compiler
17Post condition rule
- Informally, subtype is allowed to strengthen the
post condition - Formally
- pre_super post_sub - post_super
- Super // Effects returns y lt 5
- Sub //Effects returns y lt 4
- Sub //Effects returns y lt 6
- Which one is a stronger condition?
18Same Diagram as Method Verification
Supertype State (Post-Super)
Supertype State (Pre-Super)
SuperType Method Contract
?
AF()
AF()
Subtype State (Post-Sub)
Subtype State (Pre-Sub)
Subtype Method Contract
19Examples
Satisfies Signature and Method rules
- Sub
- public void addZero()
- //post add zero to this
- public void addZero() throws ISE
- //post if this is empty, throw ISE else add zero
to this
- Super
- public void addZero()
- //pre this is not empty
- //post add zero to this
- public void addZero() throws ISE
- //pre this is not empty
- //post add zero to this
Satisfies Signature and Method rules
20More examples
- Sub
- public void addZero() throws ISE
- //post add zero to this
- public void addZero()
- //post add zero to this
- Super
- public void addZero()
- //pre this is not empty
- //post add zero to this
- public void addZero() throws ISE
- //post if this is empty, throws ISE
- // else add zero to this
Does not satisfy Signature rule
Does not satisfy Postcondition part of methods
rule
21A Java Example
- What may subtypes of Iterator do?
22Client code
- private void foo
-
- try
- o.addZero()
- (catch ISE)
- //do something Client expects to get here!
-
23Methods rule vs. Properties rule
- Methods rule is for single method invocation
- Properties rule about abstract objects.
- Invariants E.g. IntSets do not contain
duplicates - s.isIn(x) following s.remove(x) always false
- Evolution properties E.g. MonotoneSets only
grow (no remove method allowed).
24Liskov 7.8, 7.9, 7.10
- public class Counter // Liskov 7.8
- public Counter() //EFF Makes this contain 0
- public int get() //EFF Returns the value of
this - public void incr() //MOD this //EFF Increments
value of this -
- public class Counter2 extends Counter // Liskov
7.9 - public Counter2() //EFF Makes this contain 0
- public void incr() // MOD this //EFF double
this -
- public class Counter3 extends Counter //
Liskov 7.10 - public Counter3(int n) //EFF Makes this contain
n - public void incr(int n) // MOD this //EFF if
ngt0 add n to this -
25Anaylsis
- Signature rule Careful with over- load vs. ride
- Counter2 ok?
- Counter3 ok?
- Methods rule
- Precondition rule
- Counter 2 ok?
- Counter 3 ok?
- Postcondition rule
- Counter 2 ok?
- Counter 3 ok?
26More About Properties Rule
- Collection ltStringgt c ...
- c.add (cat)
- c.add (cat)
- c.remove(cat)
- // consider the following observer call
- // What is behavior if c is a Set?
- // What is behavior if c is a Bag?
- if (c.contains(cat) ...
- // Such algebraic relations are extremely
useful for testing