1 / 25

Polymorphism

Polymorphism. Liskov 8. 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. A word about equals. Problem:

Download Presentation

Polymorphism

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Polymorphism Liskov 8

  2. 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

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

  4. 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

  5. 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);

  6. 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 = {[], []} ??? !!!!

  7. Liskov’s Solution • Liskov’s approach to equals() avoids this problem • Mutable objects compared via “==“ • A workaround for Java’s decision public 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

  8. 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

  9. What is Polymorphism? • 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

  10. 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?

  11. 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

  12. Comparable Interface (fig 8.4) public interface Comparable <T> { //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 (T 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

  13. 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?

  14. 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); }

  15. 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

  16. 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

  17. 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”?

  18. Comparator interface public interface Comparator <T> { public int compare (T x, T 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?

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

  20. SFBC implementation public class SFBC implements Comparator<String> { public int compare (String x, String y){ if (x==null || y == null) throw new NPE(); … //compare sx and sy from back.. } }

  21. How does client use SFBC? String n = “cat”; String p = “dog”; int m = (new SFBC()).compare(n,p); Or Set<String> set = new TreeSet<String> (new SFBC()); Iterator<String> itr = set.iterator(); // AF (itr) = [dog, cat]

  22. 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

  23. Implementation public class RC<T extends Comparable<T>> implements Comparator<T> { //O: Reverse the natural order of elements. Eg: 7<3 here public int compare (T x, T y) throws NPE, CCE { return –x.compareTo(y); }

  24. How about absolute comparison? public class AbsoluteComparator implements Comparator<Integer> //O: Compare on absolute value of (Integer) elements public int compare (Integer a, Integer b) throws NPE, CCE { 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?

  25. 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

More Related