1 / 34

Type Hierarchies

Type Hierarchies. Type Hieararchy. Why?: Want to define family of related types. At the top of the hierarchy, a type whose spec defines behavior common to all family members Two different ways: Multiple implementations of a type: Two-level hieararchy Example: phoneBook w/ Hashtable

efia
Télécharger la présentation

Type Hierarchies

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. Type Hierarchies

  2. Type Hieararchy • Why?: Want to define family of related types. • At the top of the hierarchy, a type whose spec defines behavior common to all family members • Two different ways: • Multiple implementations of a type: • Two-level hieararchy • Example: • phoneBook w/ Hashtable • phoneBook w/ Vector • Different types do not add any new behavior • Except, each has its own constructors • Different subtypes extend behavior of their supertypes • Examples: Additional methods • Supertype’s behavior must be satisfied by subtype • Called the substitution principle • The “is” relationship • Can replace an object of the subtype whenever object of the supertype is required

  3. Assignment • Apparent vs. actual type • Suppose Poly p1 = new DensePoly(); //the zero Poly Poly p2 = new SparsePoly(3, 20); // the Poly 3x20 • Variable of type Poly can refer to DensePoly or SparsePoly objects • Compiler does checking based on apparent type • Cannot invoke a DensePoly only method on p1 • But DensePoly dp = (DensePoly) p1; dp.densePolyMethod() … is legal Poly SparsePoly DensePoly

  4. Dispatching • Example: Poly p1 = new DensePoly(); int n = p1.degree(); • Both Poly and DensePoly have their own version of the degree() method • Example Static Poly diff(Poly p) { //differentiates p int g = p.degree(); ... } • Dispatching: Figuring out which one to call • Checking done based on apparent type • Execution during run-time based on actual type

  5. Defining a Type Hierarchy • First step: Define type at top of hierarchy • May not be a complete specification • May lack constructors, some methods • Subtypes • Provide constructors • Additional methods • Change behavior of some supertype methods • Good programming practice allows only limited changes • Must provide new specification • Subtype implementations contain • Instance variables defined in supertype • Methods provided in supertype • Except private constructors

  6. Defining Hierarchies • Supertypes come in three flavors • Classes (concrete classes): • All methods implemented • Abstract classes • Some methods implemented, some not • Some fields • No objects of an abstract class • Interfaces • No methods implemented • Why have these? • ActionListener example

  7. Defining Hierarchies • Methods • Normal vs. final methods • Final methods cannot be overridden • Abstract methods • Methods with no implementations • These distinctions interesting only to implementors • Not to users!!! • Representations for subtypes include instance variables for • Supertype • and itself • Subtype can access supertype fields (instance variables) only if declared as protected • But protected variables are also package visible • Better if subclass only accesses superclass through public interface. Gives full modularity.

  8. A Simple Example public class IntSet { //OVERVIEW: IntSets are mutable , unbounded sets of //integers. A typical IntSet is {x1, ... , xn} //constructors public IntSet() //EFFETCS: Initializes this to be empty. //methods public void insert (int x) //MODIFIES: this //EFFETCS: Adds x to the elements of this. public void remove (int x) //MODIFIES: this //EFFECTS: Removes x from this. public boolean inIn (int x) //EFFECTS: If x is in this returns true else //returns false. Continued next page

  9. A Simple Example public int size () //EFFETCS: Returns the cardinality of this. public boolean subset (IntSet s) //EFFECTS: Returns true if this is a subset of s //else returns false. }

  10. A Simple Example public class IntSet { private ArrayList<int> els; // the elements public IntSet () { els = new ArrayList<int> (); } private int getIndex (Integer x) { ... } private boolean isIn (int x) { return getIndex(new Integer(x)) >= 0; } public boolean subset (IntSet s) { if (s == null) return false; for (int i = 0; i < els.size(); i++) if (!s.is In(((Integer) els.get(i)).intValue())) return false; return true; } // implementations of other methods go here } • Observe • No protected methods • Concrete class: All methods implemented

  11. public class MaxIntSet extends IntSet public class MaxIntSet extends IntSet { //OVERVIEW: MaxIntSet is a subtype of IntSet with an //additional method, max, to determine the maximum //element of the set. //constructors public MaxIntSet () //EFFECTS: Makes this to be empty MaxIntSet. //methods public int max () throws EmptyException //EFFECTS: If this is empty throws EmptyException // else returns the largest element of this. } • Only new methods need to be specified • New field: private int biggest; //the max element (if set is not empty)

  12. MaxIntSet Constructor public MaxIntSet () { } automatically calls public MaxIntSet () { super() }; • Subtype constructor must call supertype constructor • Otherwise, supertype constructor with no arguments is called automatically

  13. MaxIntSet Implementations public class MaxIntSet extends IntSet { private int biggest; //the biggest element if set is not empty public MaxIntSet () { super(); } public void insert (int x) { if (size () == 0|| x > biggest) biggest = x; super.insert(x); } 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; } } Continue next page

  14. A Simple Example public int max () throws EmptyException { if (size() == 0) throw new EmptyException (“MaxIntSet.max); return biggest; } }

  15. Abstract Classes • Abstract class: Partial implementation of a type • May have instance variables, constructors, implementation of some methods • Constructors initialize supertype’s portion of the implementation • Allows code reuse, reliability • Some methods left unimplemented • Called abstract methods public boolean subset (IntSet s) //inherited public boolean subset (SortedIntSet s) // extra

  16. Abstract Classes public class SortedIntSet extends IntSet { //OVERVIEW: A sorted int set is an int set whose elements are //accessible in sorted order. //constructors: public sortedIntSet() //EFFECTS: Make this be an empty sorted set //methods: public Iterator elements() //EFFECTS: Returns a generator that will produce all //elements of this, each exactly once, in ascending order. //REQUIRES: this not be modified while the generator is in use. public int max() throws EmptyException //EFFECTS: If this is empty throws EmptyException else //returns the largest element of this. public boolean subset (SortedIntSet s) } • has two subset methods public boolean subset (IntSet s) //inherited, no spec public boolean subset (SortedIntSet s) // extra, for // better performance

  17. Abstract Classes • If subtype wants to use its own rep and not use the supertype’s, there’s no way to do so • In that case, make supertype abstract • No rep, therefore no objects of that type • No way for users to call constructor of abstract supertype

  18. Abstract Classes public abstract class IntSet { protected int sz; // the size //constructors public IntSet () { sz = 0; } //abstract methods public abstract void insert (int x); public abstract void remove (int x); public abstract Iterator elements (); public abstract boolean reOk (); Continued next page

  19. Abstract Classes //methods public boolean isIn (int x) { Iterator g = elements (); Integer z = new Integer(x); while (g.hasnext()) if (g.next().equals(z)) return true); return false; } public int size () { return sz; } // implementations of subset and toString go here publıc boolean subset (IntSet otherSet) } • size() could have been implemented using the elements() iterator • But would be inefficient • All subtypes need efficient size() implementation • Provide field sz and size() implementation • Allow subtypes access to sz

  20. Interfaces • Interfaces • Define a type • Provide no implementation • Useful for providing multiple supertypes • Can implement many interfaces • But can extend only one class public class SortedIntSet extends ıntSet implements sortedCollection { ... }

  21. Interfaces public interface Iterator { public boolean hasNext (); //EFFECTS: Returns true if there are more items to //produce else returns false. public Object next () throws NoSuchElementException; //MODIFIES: this //EFFECTS: If there are no more items to produce, //throw NoSuchElementException. Otherwise retuns //the next item and changes the state of this to //reflect the return. }

  22. Multiple Implementations • Different implementations of a type • Some implementations more efficient for a subset of objects • E.g. Sparse vs. dense polynomials • Implementation subclasses invisible to users • Only referred to when creating new objects Poly p1 = new DensePoly(); Poly p2 = new SparsePoly(); • After some manipulation, p1 may refer to a SparsePoly and p2 may refer to a DensePoly

  23. Multiple Implementations Example: Lists public abstract class IntList { //OVERVIEW: IntLists are immutable lists of Objects. A //typical IntList is a sequence [x1,..., xn]. //methods public abstract Object first () throws EmptyException; //EFFECTS: If this is empty throws EmptyException //else returns the first element of this. public abstract Intlist rest () throws EmptyException; //EFFECTS: If this is empty throws EmptyException //else returns the list containing all but the //first element of this, in the original order. public abstract Iterator elements (); //EFFECTS: Returns a generator that will produce //the elements of this, each exactly once, in the //order in this. Continue next page

  24. Lists public abstract IntList addEl (Object x); public abstract int size (); //EFFECTS: Returns a count of the number of //elements of this. public abstract boolean repOk (); public String toString () public boolean equals (IntList o); }

  25. List Implementation as Abstract Class public abstract class IntList { //OVERVIEW: Intlists are immutable lists of objects. A typical IntList is a sequence [x1, ..., xn] //abstract methods public abstract Object first () throws EmptyException; public abstract IntList rest () throws EmptyException; public abstract Iterator elements (); public abstract IntList addEl (Object x); public abstract int size (); //methods public String toString () { ... } Continue next page

  26. List Implementation as Abstract Class public boolean equals (Object o) { try { return equals ((IntList) o); } catch (ClassCastException e) { return false; } } public boolean equals (IntList o) { //compare elements using elements iterator } }

  27. Implementation 1: Empty List public class EmptyIntList extends IntList { public EmptyList () { }; public Object first () throws EmptyException { throw new EmptyException(“EmptyIntList.first”); } public IntList addEl (Object x) { return new FullIntList(x); } // not independent of // other implementation public boolean repOk () { return true); } public StringtoString () { return“IntList: []”; } public boolean equals (Object x) { return (x instanceof EmptyIntList); } //implementations of rest ans size go here public Iterator elements () { retun new EmptyGen(); } Continue next page

  28. Implementation 1: Empty List static private class EmptyGen implements Iterator { EmptyGen () { } public boolean hasNext () { return false; } public Object next() throw NoSuchElementException { throw new NoSuchElementException(“IntList.elements”); } } //end EmptyGen } Continue next page

  29. Implementation 2: FullIntList Public class FullIntList extends IntList { private int sz; private Object val; private IntList next; public FullIntList (Object x) { sz = 1; val = x; next = new EmptyIntList(); } // not independent of other implementation public Object first () { return val; } public Object rest () { return next; } public IntList addEl (Object x) { FullIntList n = new FullIntList(x); n.next = this; n.sz = this.sz + 1; return n; } // implementations of elements, size, repOk go here }

  30. Example: Polynomial Superclass public abstract class Poly { protected int deg; //the degree //constructor protected Poly (int n) { deg = n; } //abstract methods coeff, repOk, add, mul, minus, terms //methods public int degree () { return deg; } public boolean equals (Object o) { try { return equals((Poly) o); } catch (ClassCastException e) { return false; } } Continue next page

  31. Polynomials public boolean equals (Poly p) { if (p == null || deg != p.deg) return false; Iterator tg = terms(); Iterator pg = p.terms(); while (tg.hasNext()) { int tx = ((Integer) tg.next()).intValue(); int px = ((Integer) pg.next()).intValue(); if (tx != px || coeff(tx) != p.coeff(px) return false); } return true; } public sub (Poly p) { return add(p.minus()); } public String toString () { ... } }

  32. Implementation 1: DensePoly private class DensePoly extends Poly { private int[] trms; //coefficients up to degree private DensePoly () { super(0); trms = new int[1]; } public DensePoly (int c, int n) throws NegExpExceptio { ... } private Densepoly (int n) { super(n); trms = new int[n+1]; } //implementation of coeff, add, mul, minus, terms and repOk go here public Poly add (Poly q) throws NullPointerException { if (q instanceof SparsePoly) return q.add(p); DensePoly la, sm; Continue next page

  33. if (deg > q.deg) { la = this; sm = (DensePoly) q; } else { la = (DensePoly) q; sm = this; } int newdeg = la.deg; //new degree is the larger //degree if (sm.deg == la.deg) //unless there are trailing //zeros for (int k = sm.deg; k > 0; k--) if (sm.trms[k] + la.trms[k] != 0) break; else newdeg--; DensePoly r = new DensePoly(newdeg); //get a new //densePoly int i; for (i = 0; , i <= sm.deg && i <= newdeg; i++) r.rtms[i] = sm.trms[i] + la.trms[i]; for (int j = i; j <= newdeg; j++) r.trms[j] = la.trms[j]; return r; } }

  34. How to enable users to ignore different implementations? • Make new “factory” class public class polyProcs { public static Poly makePoly () //EFFECTS: Returns the zero Poly. return new DensePoly() public static Poly makePoly (int c, int n) throws NegExpException //EFFECTS: If n < 0 throws NegExpException //else returns the monomial cxn. return new SparsePoly(c comma n) }

More Related