Polymorphism SWE 619, Last Updated Fall 2008.

Slides:



Advertisements
Similar presentations
Data Structures A data structure is a collection of data organized in some fashion that permits access to individual elements stored in the structure This.
Advertisements

Identity and Equality Based on material by Michael Ernst, University of Washington.
SUMMARY: abstract classes and interfaces 1 Make a class abstract so instances of it cannot be created. Make a method abstract so it must be overridden.
The Substitution Principle SWE 332 – Fall Liskov Substitution Principle In any client code, if subtype object is substituted for supertype object,
Composition CMSC 202. Code Reuse Effective software development relies on reusing existing code. Code reuse must be more than just copying code and changing.
Data Abstraction II SWE 619 Software Construction Last Modified, Spring 2009 Paul Ammann.
C12, Polymorphism “many forms” (greek: poly = many, morphos = form)
CS 106 Introduction to Computer Science I 04 / 30 / 2010 Instructor: Michael Eckmann.
Specifications Liskov Chapter 9 SWE 619 Last Updated Fall 2008.
Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes.
CS2110: SW Development Methods Textbook readings: MSD, Chapter 8 (Sect. 8.1 and 8.2) But we won’t implement our own, so study the section on Java’s Map.
Cs205: engineering software university of virginia fall 2006 Data Abstraction David Evans
Recitation 4 Abstract classes, Interfaces. A Little More Geometry! Abstract Classes Shape x ____ y ____ Triangle area() base____ height ____ Circle area()
SWE 619 © Paul Ammann Procedural Abstraction and Design by Contract Paul Ammann Information & Software Engineering SWE 619 Software Construction cs.gmu.edu/~pammann/
Hello.java Program Output 1 public class Hello { 2 public static void main( String [] args ) 3 { 4 System.out.println( “Hello!" ); 5 } // end method main.
Effective C#, Chapter 1: C# Language Elements Last Updated: Fall 2011.
23-Oct-15 Abstract Data Types. 2 Data types A data type is characterized by: a set of values a data representation, which is common to all these values,
COP-3330: Object Oriented Programming Flow Control May 16, 2012 Eng. Hector M Lugo-Cordero, MS.
Design Patterns Gang Qian Department of Computer Science University of Central Oklahoma.
Chapter 10 Defining Classes. The Internal Structure of Classes and Objects Object – collection of data and operations, in which the data can be accessed.
Chapter 6 Introduction to Defining Classes. Objectives: Design and implement a simple class from user requirements. Organize a program in terms of a view.
HashCode() 1  if you override equals() you must override hashCode()  otherwise, the hashed containers won't work properly  recall that we did not override.
Type Abstraction Liskov, Chapter 7. 2 Liskov Substitution Principle In any client code, if the supertype object is substituted by a subtype object, the.
Data Abstractions EECE 310: Software Engineering.
Type Abstraction SWE Spring October 05Kaushik, Ammann Substitution Principle “In any client code, if supertype object is substituted.
Programming with Java © 2002 The McGraw-Hill Companies, Inc. All rights reserved. 1 McGraw-Hill/Irwin Chapter 5 Creating Classes.
Csci 490 / Engr 596 Special Topics / Special Projects Software Design and Scala Programming Spring Semester 2010 Lecture Notes.
Polymorphism Liskov 8. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism.
Data Abstraction SWE 619 Software Construction Last Modified, Spring 2009 Paul Ammann.
Chapter 11: Advanced Inheritance Concepts. Objectives Create and use abstract classes Use dynamic method binding Create arrays of subclass objects Use.
Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element.
Iteration Abstraction SWE Software Construction Fall 2009.
Collections Dwight Deugo Nesa Matic
David Evans CS201J: Engineering Software University of Virginia Computer Science Lecture 5: Implementing Data Abstractions.
More constructors 1. Constructors  recall that a public constructor is what a client uses to create an object  the purpose of a constructor is to initialize.
9.1 CLASS (STATIC) VARIABLES AND METHODS Defining classes is only one aspect of object-oriented programming. The real power of object-oriented programming.
EECE 310: Software Engineering
Modern Programming Tools And Techniques-I
The List ADT.
Searching.
EECE 310: Software Engineering
Chapter 19 Java Data Structures
Inheritance and Polymorphism
Methods Attributes Method Modifiers ‘static’
Interfaces.
Specifications Liskov Chapter 9
Interfaces and Inheritance
Type Abstraction SWE Spring 2009.
Iteration Abstraction
Java Programming Language
Week 6 Object-Oriented Programming (2): Polymorphism
Abstract Class As per dictionary, abstraction is the quality of dealing with ideas rather than events. For example, when you consider the case of ,
Type Abstraction Liskov, Chapter 7.
Data Abstraction David Evans cs205: engineering software
Object Oriented Programming in java
Iteration Abstraction
SWE 619 Software Construction Last Modified, Fall 2015 Paul Ammann
Lecture 4: Data Abstraction CS201j: Engineering Software
OO Design with Inheritance
Defining Classes and Methods
More About Inheritance & Interfaces
The Java switch Statement
Chapter 9 Carrano Chapter 10 Small Java
Chapter 8: Class Relationships
Chapter 14 Abstract Classes and Interfaces
Defining Classes and Methods
CS2013 Lecture 7 John Hurley Cal State LA.
Assertions References: internet notes; Bertrand Meyer, Object-Oriented Software Construction; 4/25/2019.
Type Abstraction SWE Spring 2013.
CMPE212 – Reminders Assignment 2 due next Friday.
Presentation transcript:

Polymorphism SWE 619, Last Updated Fall 2008

Concrete Classes, Abstract Classes, and Interfaces Type-centric Implementation-centric Defines a type and a set of operations on that type Provides implementation for each declared type operation Abstract Class Type-centric Implementation-centric Defines a type and a set of operations on that type Optionally provides implementation for declared type operations Interface Type-centric Implementation-centric Defines a type and a set of operations on that type No implementation

Implementation-centric Viewpoint Abstract Class Concrete Classes

Implementation-centric Viewpoint Note that although PlaneGeometry and SphericalGeometry each declare a within (Position,Position) method to determine if the contained Position is within a box defined by the specified Position objects, this operation is not factored into the abstract class Geometry. Certainly it could be, and later will be, but doing so now rejects the current structuring criteria of achieving implementation code reuse. Because no common implementation is available, the operation is not included in the abstract class Geometry. From an implementation-centric viewpoint, the only abstract methods necessary in Geometry are those used by concrete methods within that class.

Common type operations factored into an interface Concrete Classes

Common type operations factored into an interface Each geometry class defines five common type operations that factor into the interface Geometry. With this type structure, objects instantiated from classes PlaneGeometry and SphericalGeometry can be uniformly handled through a Geometry-typed refernce variable. During program execution, a Geometry reference variable can polymorphically attach to various PlaneGeometrery and SphericalGeometry objects, and method calls to the underlying objects execute the appropriate class implementation code. Unfortunately, this approach does not address implementation reuse.

Implementation-centric Viewpoint for reuse and polymorphic behavior Abstract Class Concrete Classes

Implementation-centric Viewpoint for reuse and polymorphic behavior From an implementation perspective, the abstract class Geometry becomes a repository for the duplicate implementations of the methods heading (Position) and within (Position, double). From a type perspective, Geometry defines all the common type operations of the two specialized geometry classes. Problem: Cartesian coordinates work adequately for small distances and spherical coordinates are great for a sphere. Radius at the equator is somewhat grater than at the poles, an ellipse more accurately describes the earth. Solution: ???

Implementation-centric Viewpoint for reuse and polymorphic behavior Abstract Class Concrete Classes

Implementation-centric Viewpoint for reuse and polymorphic behavior Previous solution assumes that EllipticalGeometry shares the common code factored out of PlaneGeometry and SphericalGeometry. Problem: New requirement for RogueGeometry class. Analysis indicates that RogueGeometry adheres to the same set of Geometry type operations, the implementation code for the methods heading (Position) and within (Position, double) is not valid. Solution: ???

Interface for type and an abstract class for implementation

Interface for type and an abstract class for implementation Interface Geometry defines the type necessary to handle the concrete classes polymorphically. Abstract class AbstractGeometry servers as an implementation repository to the common code found in the two concrete classes. Using each construct to satisfy a specific need meets the original goal. Interfaces facilitate type-centric concerns, and abstract classes satisfy the implementation-centric concerns. Important: this design is quite flexible. EllipticalGeometry extends AbstractGeometry to utilize the common implementation in that class. RougueGeometry implements the Geometry interface directly, thereby bypassing the code repository in AbstractGeometry. Bypassing AbstractGeometry’s implementation also frees RogueGeometry to extend a more appropriate base class if necessary The type defined by the Geometry interface serves as the necessary glue to polymorphically handle objects instantiated from any of the four concrete geometry classes. THE EASE IN EXTENDING THE ORIGINAL DESIGN DIRECTLY RELATES TO HAVING PROPERLY USED INTERFACES AND ABSTRACT CLASSES TO HANDLE TYPE AND IMPLEMENTATION-CENTRIC CONCERNS.

Outline equals() Polymorphism Revisiting Liskov’s mutable vs. not rule Uniform methods for different types “easy” polymorphism Element subtype approach Planning ahead Related subtype approach Reacting after the fact

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)

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

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

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

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

Outline equals() Polymorphism Revisiting Liskov’s mutable vs. not rule Uniform methods for different types “easy” polymorphism Element subtype approach Planning ahead Related subtype approach Reacting after the fact

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

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

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?

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

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

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?

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

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

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

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

Comparator interface public 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?

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)

SFBC implementation public 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.. }

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

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

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?

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?

Similarities between Comparable and Addable 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