26
Type Abstraction Liskov, Chapter 7

Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

Embed Size (px)

Citation preview

Page 1: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

Type Abstraction

Liskov, Chapter 7

Page 2: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

2

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.

Page 3: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

3

Why 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!

Page 4: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

4

Extended behavior

Extended Behavior Specialize the behavior of supertype Classic ‘IS A’ relationship Usually has additional rep.

VehicleCar Bike

Constraint View: for contracts

CAR

Object View: for rep

Vehicle

Page 5: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

5

Conflict in two goals?

Poly

SparsePoly LogPolyDensePoly

Poly

SparsePoly

LogPoly

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)

Page 6: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

6

DispatchingObject[] 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].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.

Page 7: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

7

MaxIntSet 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 > biggest) biggest = x;super.insert(x); }

public int max () throws EmptyException {if (size() == 0) throw new EmptyException

(“MaxIS.max”);return biggest; }

Page 8: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

8

MaxIntSet.remove()public void remove (int x) {

super.remove(x);if (size()==0 || x <biggest) return;Iterator g = elements();biggest = ((Integer) g.next()).intValue();while (g.hasNext() {

int z = ((Integer) g.next()).intValue();if (z>biggest) biggest = z;

} Need to call supertype’s remove functionality. (private

rep!) Must maintain subtype’s rep invariant

Page 9: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

9

MaxIntSet 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 <biggest, {x1, x2, ... xN}> - 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.

Page 10: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

10

MaxIntSet.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 (z>biggest) return false;if (z==biggest) found = true;

return found;}

Page 11: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

11

repOk() and Dynamic Dispatchingpublic 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()????

Page 12: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

12

Meaning of subtypes

Subtypes behavior must support supertype behavior – (SP)

In particular following three properties:

1. Signature Rule2. Methods Rule3. Properties Rule

Page 13: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

13

Signature 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

Page 14: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

14

Methods 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 IntSetIntSet x = new IntSet();IntSet y = new SortedIntSet();x.insert(3); //What is this_post?y.insert(3); //What is this_post?

Page 15: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

15

Methods Rule

1. Cannot take away methods!1. Subtype API should atleast be equal or

greater than supertype API

2. Must maintain the contract!1. Precondition rule: What can a subclass

do with preconditions in supertype spec?2. Post condition rule: What can a subclass

do with postconditions in supertype spec?

Page 16: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

16

Precondition rule Subtype is allowed to weaken the

precondition! Formally:

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

Page 17: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

17

Post condition rule Informally, subtype is allowed to

strengthen the post condition Formally:

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?

Page 18: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

18

Same Diagram as Method Verification

SuperType Method

Contract

Subtype Method

Contract

AF() AF()

Supertype State (Post-Super)

Supertype State (Pre-Super)

Subtype State (Post-Sub)

Subtype State (Pre-Sub)

?

Page 19: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

19

Examples 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

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

Satisfies Signatureand Method rules

Satisfies Signatureand Method rules

Page 20: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

20

More examples 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

Sub

public void addZero() throws ISE

//post: add zero to this

public void addZero()

//post: add zero to this

Does not satisfy Signature rule

Does not satisfy Postconditionpart of methods rule

Page 21: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

21

A Java Example

What may subtypes of Iterator do?

Page 22: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

22

Client code

private void foo {…try{

o.addZero();} (catch EE){

//do something: Client expects to get here!}

}

Page 23: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

23

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

Page 24: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

24

Liskov 7.8, 7.9, 7.10public class Counter{ // Liskov 7.8

public Counter() //EFF: Makes this contain 0public int get() //EFF: Returns the value of thispublic void incr() //MOD: this //EFF: Increments value of this

}public class Counter2 extends Counter { // Liskov 7.9

public Counter2() //EFF: Makes this contain 0public void incr() // MOD: this //EFF: double this

}public class Counter3 extends Counter { // Liskov 7.10

public Counter3(int n) //EFF: Makes this contain npublic void incr(int n) // MOD: this //EFF: if n>0 add n to this

}

Page 25: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

25

Anaylsis 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?

Page 26: Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the

26

More About Properties Rule

Collection <String> 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