Type Abstraction Liskov Chapter 7 Liskov Substitution Principle
Type Abstraction Liskov, Chapter 7
Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the client’s expectations will still be satisfied. Everyone learns this in intro OO courses, but this is a lot harder than it looks. 2
Why do we subtype? n Extended Behavior n n Standard “Is-A” Relationships Multiple implementations n n n Sparse. Poly, Dense. Poly Different implementations Same specifications All supertype behavior must be supported No extra stuff! 3
Extended behavior n Extended Behavior n n n Specialize the behavior of supertype Classic ‘IS A’ relationship Usually has additional rep. Bike Car Vehicle Constraint View: for contracts CAR Vehicle Object View: for rep 4
Conflict in two goals? Poly Sparse. Poly Dense. Poly Log. Poly: 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) Log. Poly 5
Dispatching Object[] x = new Object[2]; x[0] = new String(“abc”); x[1] = new Integer(1); for(int i=0; i<x. length; i++) System. out. println(x[i]. to. String()); n n n Compiler does not complain Which to. String() method is called? Object. to. String(), String. to. String() or Integer. to. String()? At run time, “best fit” code is called. 6
Max. Int. Set Example (Fig 7. 5) public class Max. Int. Set extends Int. Set { private int biggest; // biggest element of set if not empty public Max. Int. Set {super (); } //Why call super() ? ? ? public void insert (int x) { if (size() == 0 || x > biggest) biggest = x; super. insert(x); } public int max () throws Empty. Exception { if (size() == 0) throw new Empty. Exception (“Max. IS. max”); return biggest; } 7
Max. Int. Set. remove() public void remove (int x) { super. remove(x); if (size()==0 || x <biggest) return; Iterator g = elements(); biggest = ((Integer) g. next()). int. Value(); while (g. has. Next() { int z = ((Integer) g. next()). int. Value(); if (z>biggest) biggest = z; } n Need to call supertype’s remove functionality. (private rep!) n Must maintain subtype’s rep invariant 8
Max. Int. Set Abstract State // Overview: Max. Int. Set is a subtype of Int. Set with an additional // method, max, to determine the maximum element of the set n Two possible abstract states: n n n {x 1, x 2, . . . x. N} - same as Int. Set <biggest, {x 1, x 2, . . . x. N}> - visible abstract state Which one to choose? n n n 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. 9
Max. Int. Set. rep. Ok() public boolean rep. Ok() { if (!super. rep. Ok()) return false; if (size() == 0) return true; boolean found = false; Iterator g = elements(); while(g. has. Next()) { int z = ((Integer)g. next()). int. Value(); if (z>biggest) return false; if (z==biggest) found = true; return found; } 10
rep. Ok() and Dynamic Dispatching public class Int. Set { public void insert(int x) {. . . ; rep. Ok(); } public void remove(int x) {. . . ; rep. Ok(); } // where to? public boolean rep. Ok() {. . . } } public class Max. Int. Set extends Int. Set { public void insert(int x) {. . . ; super. insert(x); rep. Ok(); } public void remove(int x) {super. remove(x); . . . ; rep. Ok(); } public boolean rep. Ok() {super. rep. Ok(); . . . ; } } Max. Int. Set s = {3, 5}; s. remove(5); // rep. Ok()? ? 11
Meaning of subtypes n n Subtypes behavior must support supertype behavior – (SP) In particular following three properties: 1. 2. 3. Signature Rule Methods Rule Properties Rule 12
Signature Rule n n Subtypes must have all methods of supertype Signatures of methods must be compatible with supertype signature n n n 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) {. . . } n Exceptions n n Signature Rule allows Subtype to throw fewer But methods rule must be satisfied 13
Methods Rule n n When object belongs to subtype, subtype method is called We must still be able to reason about these methods using supertype specs Suppose Sorted. Int. Set extends Int. Set x = new Int. Set(); Int. Set y = new Sorted. Int. Set(); x. insert(3); //What is this_post? y. insert(3); //What is this_post? 14
Methods Rule 1. Cannot take away methods! 1. 2. Subtype API should atleast be equal or greater than supertype API Must maintain the contract! 1. 2. 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? 15
Precondition rule n n Subtype is allowed to weaken the precondition! Formally: n n n n pre_super |- pre_sub Super //Requires: x > 5 Case 1: Sub //Requires x > 6 Case 2: Sub // Requires x > 4 x>5 x>4? Which is weaker? x>5 x>6? Not checked by compiler 16
Post condition rule n n Informally, subtype is allowed to strengthen the post condition Formally: n n n pre_super && post_sub |- post_super Super: // Effects: returns y < 5 Sub: //Effects: returns y < 4 Sub: //Effects: returns y < 6 Which one is a stronger condition? 17
Same Diagram as Method Verification Supertype State (Pre-Super) Supertype State (Post-Super) Super. Type Method Contract ? AF() Subtype State (Pre-Sub) Subtype State (Post-Sub) Method Contract 18
Examples n Super Satisfies Signature and Method rules n Sub public void add. Zero() //pre: this is not empty //post: add zero to this public void add. Zero() throws ISE //post: if this is empty, throw ISE else add zero to this Satisfies Signature and Method rules 19
More examples n Super Does not satisfy Signature rule public void add. Zero() //pre: this is not empty //post: add zero to this public void add. Zero() throws ISE //post: if this is empty, throws ISE // else add zero to this n Sub public void add. Zero() throws ISE //post: add zero to this public void add. Zero() //post: add zero to this Does not satisfy Postcondition part of methods rule 20
A Java Example n What may subtypes of Iterator do? 21
Client code private void foo { … try{ o. add. Zero(); } (catch ISE){ //do something: Client expects to get here! } } 22
Methods rule vs. Properties rule n n Methods rule is for single method invocation Properties rule about abstract objects. n Invariants: E. g. Int. Sets do not contain duplicates n n s. is. In(x) following s. remove(x) always false Evolution properties: E. g. Monotone. Sets only grow (no remove method allowed). 23
Liskov 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 Counter 2 extends Counter { // Liskov 7. 9 public Counter 2() //EFF: Makes this contain 0 public void incr() // MOD: this //EFF: double this } public class Counter 3 extends Counter { // Liskov 7. 10 public Counter 3(int n) //EFF: Makes this contain n public void incr(int n) // MOD: this //EFF: if n>0 add n to this } 24
Anaylsis n Signature rule: Careful with over- load vs. ride n n n Counter 2 ok? Counter 3 ok? Methods rule: n Precondition rule: n n n Counter 2 ok? Counter 3 ok? Postcondition rule: n n Counter 2 ok? Counter 3 ok? 25
More About Properties Rule Collection <String> c =. . . ; c. add (“cat”); c. remove(“cat”); // // // if consider the following observer call: What is behavior if c is a Set? What is behavior if c is a Bag? (c. contains(“cat”) {. . . } // Such “algebraic” relations are extremely useful for testing 26
- Slides: 26