polymorphism swe 619. outline equals() revisiting liskov’s mutable vs. not rule polymorphism...

26
Polymorphism SWE 619

Upload: elmer-long

Post on 18-Jan-2018

224 views

Category:

Documents


0 download

DESCRIPTION

A word about equals Problem: We want to check if two objects are equal to each other Many ways to do so: Object identity [A==B] (same object) Object state [A.counter = B.counter] (similar objects) Object property [A.area() = B.area()] (practically same)

TRANSCRIPT

Page 1: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

Polymorphism

SWE 619

Page 2: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

Outline equals()

Revisiting Liskov’s mutable vs. not rule Polymorphism

Uniform methods for different types “easy” polymorphism

Element subtype approach Planning ahead

Related subtype approach Reacting after the fact

Page 3: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

A word about equals Problem:

We want to check if two objects are equal to each other

Many ways to do so: Object identity [A==B] (same object) Object state [A.counter = B.counter]

(similar objects) Object property [A.area() = B.area()]

(practically same)

Page 4: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

Overriding equals Object class equals is ‘==‘ check Overriding equals means providing a

check other than object identity. Usually it provides object state check

Overriding equals in a mutable class A.equals(B) is true/false at different

times Immutable classes don’t suffer from

this problem

Page 5: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

How to get in trouble: Storing mutable types in collections Assume a collection that does not

allow duplicates (eg java.util.TreeSet) Aim: to store mutable types with

overridden equals.void insert (Object x) {

for all elements in collection{if (element[i].equals(x)) return; // no duplicates} collection.addElement(x);

Page 6: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

What’s the Problem?Consider client code for fig 8.1:Set s = new HashSet(); // AF(s) = {}Vector x = new Vector() // AF(x) = []Vector y = new Vector() // AF(y) = []s.insert(x); // AF(s) = {[]}s.insert(y); // AF(s) = {[], []}? Or {[]}?s.contains(y) // true or false?y.add(“cat”); // AF(y) = [“cat”] // AF(s) = ?????s.contains(y); // true or false?s.insert(y); // s.state = {[], [“cat”]}???y.remove(“cat”); // s.state = {[], []} ??? !!!!

Page 7: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

Solution Liskov’s approach to equals() avoids this

problem Mutable objects compared via “==“

A workaround for Java’s decisionpublic boolean equals (Object x) {if (!x instanceOf Container) return false;return (el == ((Container) x.el));}

Equality does not pose a problem anymore! We can insert both x and y in s. Even if x modified, we will still find y in s

Page 8: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

Outline equals()

Revisiting Liskov’s mutable vs. not rule Polymorphism

Uniform methods for different types “easy” polymorphism

Element subtype approach Planning ahead

Related subtype approach Reacting after the fact

Page 9: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

What is Polymorphism? Abstraction? Generalization? Abstracts from the type of data,

parameter E.g.: java.util classes Vector,

Dictionary and others can store any object like: Integer, Float, String, Reader etc.

Compare with IntSet, which could only store Integers

Page 10: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

What is it? Generalize abstractions

They should work for many types E.g.: IntSet could be generalized to Set

Not just store integers, but other data types Saves us from creating new data

abstractions for each data type (like PolySet, FloatSet, etc.)

Compare IntSet with HashSet, TreeSet

Page 11: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

Polymorphic procedures Procedures can be polymorphic with

respect to types of arguments E.g.: Intset.insert(int x) becomes

Set.Insert(Object x) or overloaded Set.Insert(…) with the specified list of types

How does this affect specs of procedures?

Page 12: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

Polymorphic Data abstractions Two kinds: element subtype (Comparable, Addable)

Pre planning. Unique way for all subtypes

related subtype (Comparator, Adder) post planning, class designer did not provide it create a related type for each object type

Both kinds use interfaces for generalization

Page 13: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

Comparable Interface (fig 8.4)public Interface Comparable {

//O: Subtypes of Comparable provide a method to determine the ordering of their objects. This ordering must be a total order over their objects, and it should be both transitive and antisymmetric. Furthermore, x.compareTo(y)== 0 implies (iff???) x.equals(y).

public int compareTo (Object x) throws CCE, NPE;//E: If x is null, throws NPE; if this and x aren’t compatible, throws CCE. Otherwise, if this is less than x returns <0; if this equals x, returns 0 and if this is greater than x, returns >0

Page 14: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

OrderedList (Figure 8.5) Stores elements which implement

Comparable interface Bug in addEl() (first line)

“if (val == null)” should be “if (el == null)”

Specs: order of exceptions! Very similar to TreeSet What is the abstract state?

Page 15: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

Ordered List code (fig 8.5)

public class OL { private boolean empty; private OL left, right; private Comparable val;public void addEl(Comparable el) throws NPE,DE,CCE // M: this // E: if el is null throw NPE else if el is in this

throw DE else if el is incomparable to elements in this throw CCE else add el to this

if (el == null) throw new NPE(...) if (empty) {left = new OL(); right = new OL(); val = el;

empty = false; return;} int n = el.compareTo(val); if (n == 0) throw new DE(...); if(n < 0) left.addEl(el); else right.addEl(el); }

Page 16: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

Related subtype approach After classes have been designed We want a collection to store and

operate on any of such types Some client code may already

exist! We don’t want it to break. So we create related subtype Accompanies each type, supports

desired operations

Page 17: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

Related subtype Example problem (figure 8.8):

We want to sum up all the elements in a set. SumSet class must maintain a running sum of all Integers, Floats or Poly’s stored. We store one type of object at a time SumSet a stores only Polys SumSet b stores only Integers

Page 18: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

SumSet Implementation (Fig 8.8)

public class SumSet { private Vector els; private Object s; private Adder a; public SumSet(Adder p) throws NPE { els = new Vector(); a = p; s = p.zero();}public void insert(Object x) throws NPE, CCE {

// M: this // E: if x is null throw NPE; if x cannot be added to this // throw CCE; else adds x to this and adjusts the sum Object z = a.add(s, x); if (!els.contains(x)) { els.add(x); s = z; }public Object sum() { //E: return sum of elements in this return s; }} Note order of exceptions What’s an “Adder”?

Page 19: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

Comparator interfacepublic Interface Comparator {

public int compare (Object x, Object y) throws NPE, CCE;//E: IF x,y = null, throws NPE; // If x and y are not comparable, throws CCE// If x less than y, returns -1; if x is equal to y, returns 0; if x greater than y, returns 1

}

Why two parameters in compare()? How does client use it?

Page 20: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

StringFromBackComparator String.compareTo(String) method

provides a dictionary like ordering. (lexicographical ordering)

What if we want a different ordering? For example: We want to compare

strings from back. “cat”.comparison(“dog”) should return 1

We can achieve so by implementing our own Comparator: StringFromBackComparator (SFBC)

Page 21: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

SFBC implementationpublic class SFBC implements Comparator {

public int compare (Object x, Object y){if (x==null || y == null) throw new NPE(“msg”);String sx = (String) x ; // CCE automatically

String sy = (String) y; // CCE automatically

… //compare sx and sy from back..}

}

Page 22: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

How does client use SFBC?String n = “cat”;String p = “dog”;int m = (new SFBC()).compare(n,p);

Page 23: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

E.g.: ReverseComparator We are not satisfied by

comparable.compareTo() method. We cannot change it! Alternate way: use Comparator to

define our own criteria Here, we want to reverse the

evaluation of Comparable.compareTo

Page 24: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

Correct implementation?public class ReverseComparator implements Comparator

//O: Reverse the natural order of elements. Eg: 7<3 here

public int compare (Object x, Object y) throws NPE, CCE{return –((Comparable x).compareTo((Comparable) y));}

Is this correct implementation? Look at methods rule contract What does client expect?

Page 25: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

How about absolute comparison?public class AbsoluteComparator implements Comparator

//O: Compare on absolute value of (Integer) elements public int compare (Object x, Object y) throws NPE, CCE

{ int a = ((Integer) x).intValue();

int b = ((Integer) y).intValue(); if (a < 0) a = -a; if (b < 0) b = -b; // absolute values if (a < b) return -1; if (a > b) return 1; return 0;

} Is this correct?

Page 26: Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element

Similarities between Comparable and Addable Comparable

Provides uniform way to compare elements

Abstracts from types

All types compared in a similar manner

Addable

Provides uniform way to add elements

Abstracts from types

All types added in a similar manner