COSC2767: Object-Oriented Programming

52
1 COSC2767: Object- Oriented Programming Haibin Zhu, Ph. D. Associate Professor of CS, Nipissing University

description

COSC2767: Object-Oriented Programming. Haibin Zhu, Ph. D. Ass ociate Professor of CS, Nipissing University. Lecture 8. The Polymorphic Variable and Generics. Polymorphic variable. A polymorphic variable is a variable that can hold values of different types during the course of execution. - PowerPoint PPT Presentation

Transcript of COSC2767: Object-Oriented Programming

Page 1: COSC2767: Object-Oriented Programming

1

COSC2767: Object-Oriented Programming

Haibin Zhu, Ph. D.Associate Professor of CS,

Nipissing University

Page 2: COSC2767: Object-Oriented Programming

2

Lecture 8

The Polymorphic Variable and Generics

Page 3: COSC2767: Object-Oriented Programming

3

Polymorphic variable A polymorphic variable is a variable

that can hold values of different types during the

course of execution.

Page 4: COSC2767: Object-Oriented Programming

4

Simple Polymorphic Variables

public class Solitaire { ... static CardPile allPiles [ ]; ...

public void paint(Graphics g) { for (int i = 0; i < 13; i++) allPiles[i].display(g); } ... }

The variable was declared as CardPile, but actually held a number of different types.

Page 5: COSC2767: Object-Oriented Programming

5

The Receiver Variable

The most common polymorphic variable is the one that holds the receiver during the execution of a method.

Call this in C++ and Java, self in Smalltalk and Objective-C, current in Eiffel.

Holds the actual value (the dynamic class) during execution, not the static class.

Page 6: COSC2767: Object-Oriented Programming

6

The Receiver Variable in Frameworks

The greatest power of the receiver variable comes in the development of software frameworks.

In a framework, some methods are implemented in the parent class and not overridden (called foundation method), others are defined in the parent class, but intended to be overridden (called deferred method).

Consider a class Window with subclasses TextWindow and GraphicsWindow.

The combination of foundation and deferred methods allow high level algorithms to be reused and specialized in new situations.

Page 7: COSC2767: Object-Oriented Programming

7

Example, Repainting Window

class Window { public void repaint () { // invoke the deferred method paint. // Because the implicit receiver, this, // is polymorphic, the method from the // child class will be executed paint (graphicsContext); } abstract public void paint (Graphics g); // deferred private Graphics graphicsContext; } class GraphicsWindow extends Window { public void paint (Graphics g) { // do the appropriate painting job } } Window w= new GraphicsWindow(); w.repaint(); Only the child class knows how to paint the window. The receiver variable is responsible

for remembering the actual class of the receiver when executing the method in the parent class.

Page 8: COSC2767: Object-Oriented Programming

8

Self and Super In Java and Smalltalk there is another pseudo-variable, named super. Super is like self, only when a message is given to super it looks for

the method in the parent class of the current class. class Parent { void exampleOne () { System.out.println("In parent method"); } } class Child extends Parent { void exampleOne () { System.out.println("In child method"); super.exampleOne(); } }//Super.java Variable is called base in C#.

Page 9: COSC2767: Object-Oriented Programming

9

Downcast (Reverse Polymorphism)

It is sometimes necessary to undo the assignment to a polymorphic variable.

That is, to determine the variables true dynamic value, and assign it to a variable of the appropriate type.

This process is termed down casting, or, since it is undoing the polymorphic assignment, reverse polymorphism.

Various different syntaxes are used for this, see the book.

Parent aVariable = ...; Child aCard; if (aVariable instanceof Child) aChild = (Child) aVariable;

Page 10: COSC2767: Object-Oriented Programming

10

Pure Polymorphism A polymorphic method (also called pure

polymorphism) occurs when a polymorphic variable is used as an argument. Different effects are formed by using different types of value.

class StringBuffer { String append (Object value) { return append(value.toString()); } ... }//PurePoly.java Note: this is a non-stop method! Different objects implement toString differently, so the

effects will vary depending upon the argument.

Page 11: COSC2767: Object-Oriented Programming

11

Another Example of Pure Polymorphism

This example is from Smalltalk. between: low and: high ^ (low <= self) and: [ self <= high] Different arguments will implement the relational test

differently, so different effects can be achieved. x between: $a and: $z x between: 1 and: 100 x between: 3.14 and: 4.56 x between: "abc" and: "pdq" x between: 10@5 and: 50@40

Page 12: COSC2767: Object-Oriented Programming

12

Summary of Polymorphic Variables

A polymorphic Variable is a variable that can reference more than one type of object

Polymorphic variables derive their power from interaction with inheritance, overriding and substitution.

A common polymorphic variable is the implicit variable that maintains the receiver during the execution of a method

Downcasting is the undoing of a polymorphic assignment

Pure polymorphism occurs when a polymorphic variable is used as an argument.

Page 13: COSC2767: Object-Oriented Programming

13

Generics

Page 14: COSC2767: Object-Oriented Programming

14

Generics The idea of a generic (or template) is yet

another approach to software reuse. The time, the basic idea is to develop code by leave certain key types unspecified, to be filled in later.

In many ways this is like a parameter that is filled with many different values. Here, however, the parameters are types, and not values.

Generics are used both with functions and with classes.

Page 15: COSC2767: Object-Oriented Programming

15

Templates Templates give us the means of defining a

family of functions or classes that share the same functionality but which may differ with respect to the data type used internally.

A class template is a framework for generating the source code for any number of related classes.

A function template is a framework for generating related functions.

Page 16: COSC2767: Object-Oriented Programming

16

C++ Templates

Function template Class template

Page 17: COSC2767: Object-Oriented Programming

17

Function Template template <class T> return-type function-name(T param) //one parameter function. T is called template parameter.

Page 18: COSC2767: Object-Oriented Programming

18

Function Templates A function can be defined in terms of an

unspecified type. The compiler generates separate

versions of the function based on the type of the parameters passed in the function calls.

Page 19: COSC2767: Object-Oriented Programming

19

C++ Template Functions The following illustrates a simple template function in

C++, and its use. template <class T> T max(T left, T right) { if (left < right) return right; return left; }

int a = max(3, 27); double d = max(3.14, 2.75); // see how types

differ

Page 20: COSC2767: Object-Oriented Programming

20

One parameter function template

template <class T> void Display(const T &val) { cout << val; }

One parameter function with an additional parameters which are not template parameters template <class T> void Display(const T &val, ostream &os) { os << val; }

The same parameter appear multiple times. template <class T> void Swap(T & x, T &y) { ... }

Page 21: COSC2767: Object-Oriented Programming

21

Swap

swapFunction Template

Swap2 integers

Swap 2 floats

Swap2 rationals ...

...

generic

Page 22: COSC2767: Object-Oriented Programming

22

Swap#include <iostream.h>template <class TParam>void Swap( TParam & x, TParam & y ){ TParam temp; temp = x; x = y; y = temp;}

Page 23: COSC2767: Object-Oriented Programming

23

Swap class Student { public: Student( unsigned id = 0 ) { idnum = id; } int getID() {return idnum;}; private: unsigned idnum; };

Page 24: COSC2767: Object-Oriented Programming

24

Swapint main(){int m = 10;int n = 20;Student S1( 1234 );Student S2( 5678 );cout << m<<" "<<n<<" "<<endl;Swap( m, n ); // call with integerscout << m<<" "<<n<<" "<<endl;cout << S1.getID()<<" "<<S2.getID()<<" "<<endl;Swap( S1, S2 ); // call with Studentscout << S1.getID()<<" "<<S2.getID()<<" "<<endl;return 0;}//swap.cpp

Page 25: COSC2767: Object-Oriented Programming

25

Multiple parameter function template

template <class T1, T2> void ArrayInput(T1 array, T2 & count){ for (T2 j= 0; j < count; j++)

{cout << “value:”; cin >> array[j];}

}

Page 26: COSC2767: Object-Oriented Programming

26

Multiple parameter function template

const unsigned tempCount = 3; float temperature[tempCount ]; const unsigned stationCount = 4; int station[stationCount ]; ArrayInput(temperature, tempCount); ArrayInput(station, stationCount);

Page 27: COSC2767: Object-Oriented Programming

27

Example:Table Lookup#include <iostream.h>template <class T>long indexOf( T searchVal, const T * table,

unsigned size ){ for( unsigned i=0; i < size; i++ ) if( searchVal == table[i] ) return i; return -1;}

Page 28: COSC2767: Object-Oriented Programming

28

Example:Table Lookupint main(){ const unsigned iCount = 10; const unsigned fCount = 5; int iTable[iCount] = { 0,10,20,30,40,50,60,70,80,90 }; float fTable[fCount] = { 1.1, 2.2, 3.3, 4.4, 5.5 };cout << indexOf( 20, iTable, iCount ) << endl; // "2" cout << indexOf( 2.2f, fTable, fCount ) << endl; // "1"const unsigned sCount = 5; char * names[sCount] = { "John","Mary","Sue","Dan","Bob" }; cout << indexOf( "Dan", names, sCount )<<endl; // ? return 0;}//funtemplate.cpp

Page 29: COSC2767: Object-Oriented Programming

29

Note

In the function template, if you use a operator, you must be sure every class relevant to the template will support the operator, such as “==“, etc.

Therefore, C++ provides the mechanism of operator overloading.

Page 30: COSC2767: Object-Oriented Programming

30

Example: studentclass Student {public: Student( long idVal ) { id = idVal; } int operator ==( const Student & s2 ) const { return id == s2.id; }private: long id; // student ID number};

Page 31: COSC2767: Object-Oriented Programming

31

Example: student

int main(){ const unsigned sCount = 5; Student sTable[sCount] = { 10000, 11111,

20000, 22222, 30000 }; Student s( 22222 ); cout << indexOf( s, sTable, sCount )<<endl; //

print "3" return 0;}//student.cpp

Page 32: COSC2767: Object-Oriented Programming

32

Overriding a Function Template

In some cases when the function template does not apply to a particular type, it may be necessary to either override the function template, or make the type conformant to the function

template.

Page 33: COSC2767: Object-Oriented Programming

33

The best matching principle

Find a function that matches the parameters well;

If there is no match for a specific function, find a function template to check if the parameters match one specialized form; and

If no match is found, the call is declared as an erroneous one.

If it ends up with two or more equally good matches, the call is ambiguous and an error is also reported.

Page 34: COSC2767: Object-Oriented Programming

34

Class Template Declare and define an object: template <class T> class MyClass{ //... }MyClass <int> x;MyClass <student> aStudent;

Page 35: COSC2767: Object-Oriented Programming

35

Template Classes

While template functions are useful, it is more common to use templates with classes.

template <class T> class Box { public: Box (T initial) : value(initial) { } T getValue() { return value; } setValue (T newValue) { value = newValue; } private: T value; };

Page 36: COSC2767: Object-Oriented Programming

36

Can Be Filled with Different Arguments

Box <int> iBox(7); iBox.setValue(3.1415);

// ERROR - invalid type Box <double> dBox(2.7); cout << dBox.getValue(); //2.7 dBox.setValue(3.1415); cout << dBox.getValue(); //3.1415 iBox = dBox;

// ERROR - mismatched types In the next chapter we will see how generics are

used to create collection classes.

Page 37: COSC2767: Object-Oriented Programming

37

Simple Exampletemplate <class T1, class T2>

class Circle {//...private: T1 x, y; T2 radius;};//...Circle <int, long> c1;Circle <unsigned, float> c2;

Page 38: COSC2767: Object-Oriented Programming

38

Class Template

ArrayClass Template

integerArray

floatArray

FStringArray

...

...

generic

Page 39: COSC2767: Object-Oriented Programming

39

Example: Array Class Template

template <class T>class Array {public: Array( unsigned sz ); ~Array(); T & operator[]( unsigned i );private: T * values; unsigned size;};

Page 40: COSC2767: Object-Oriented Programming

40

Example: Array Class Template

template<class T> Array<T>::Array( unsigned sz ){ values = new T [sz]; size = sz;}template<class T> T & Array<T>::operator[] ( unsigned

i ){ if( i >= size ) throw RangeError(__FILE__,__LINE__,i); return values[i];}template<class T> Array<T>::~Array(){ delete [] values;}

Page 41: COSC2767: Object-Oriented Programming

41

Example: Array Class Template

int main(){ const unsigned numDives = 2; Array<int> diveNum( numDives ); Array<float> difficulty( numDives ); Array<FString> diveName (numDives); int j; for(j = 0; j < numDives; j++) {cout << "Enter dive #, difficulty level, dive name "; cin >> diveNum[j] >> difficulty[j] >> ws; diveName[j].GetLine( cin ); } for(j = 0; j < 2; j++) cout << diveName[j] << '\n'; cout << endl; return 0;}//array.cpp, Fstring.cpp, Fstring.h, range.h, array.h

Page 42: COSC2767: Object-Oriented Programming

42

Templates and Inheritances

Template is not a class No inheritances for a template

A class based on a template is an ordinary class

class t1 : public Array {...}//OK!!!

templat <class T> class Myclass: public Array {//OK!!! }

Page 43: COSC2767: Object-Oriented Programming

43

Inheritance and Generics Remember the class Box. Suppose a class Person has

subclasses BoyChild and GirlChild. What is the relationship between Box<Person> and Box<BoyChild>?

Unfortunately, runs into problems with the principle of substitution.

Assume Box<BoyChild> is a subclass of Box<Person>, would make the following legal:

Box<Person> aBox = new Box<BoyChild>; Person aGirl = new GirlChild; aBox.set(aGirl); A similar argument can be made for the reverse.

Page 44: COSC2767: Object-Oriented Programming

44

Inheritance and Arrays Can make a similar argument for arrays: BoyChild [ ] boys = new BoyChild[10];

Person [ ] people = boys; // copy or pointer semantics?

GirlChild sally = new GirlChild;

people[1] = sally;

If pointer semantics are used for the array assignment then this can produce type errors. Java allows the assignment, but uses a run-time check to catch the last assignment error!

Other languages make the array assignment illegal.

Page 45: COSC2767: Object-Oriented Programming

45

Templates and static members

Keep in mind again: Template is not class, only template.

Static members defined in a template are static members of the classes of this template.

Page 46: COSC2767: Object-Oriented Programming

46

Java Generics List ArrayList LinkedList Vector

http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

Page 47: COSC2767: Object-Oriented Programming

47

Java List A List (sometimes called a sequence) is an ordered

Collection that can contain duplicate elements. Like array indices, List indices are zero based (i.e.,

the first element’s index is zero). In addition to the methods inherited from Collection,

List provides methods for manipulating elements via their indices, manipulating a specified range of elements, searching for elements and getting a ListIterator to access the elements.

Interface List is implemented by several classes, including classes ArrayList, LinkedList and Vector.

http://java.sun.com/j2se/1.4.2/docs/api/java/util/List.html

Page 48: COSC2767: Object-Oriented Programming

48

ArrayList and LinkedList Class ArrayList and Vector are resizable-array

implementations of List. Class LinkedList is a linked-list implementation of

interface List. Class ArrayList’s behavior and capabilities are similar to

those of class Vector. The primary difference between Vector and ArrayList is

that objects of class Vector are synchronized by default, whereas objects of class ArrayList are not.

//CollectionTest.java //ListTest.javahttp://java.sun.com/j2se/1.5.0/docs/api/java/util/ArrayList.html

http://java.sun.com/j2se/1.4.2/docs/api/java/util/LinkedList.html

http://72.5.124.55/j2se/1.4.2/docs/api/java/util/ListIterator.html

Page 49: COSC2767: Object-Oriented Programming

49

ListIterator An iterator for lists that allows the programmer to

traverse the list in either direction, modify the list during iteration, and obtain the iterator's current position in the list.

A ListIterator has no current element; its cursor position always lies between the element that would be returned by a call to previous() and the element that would be returned by a call to next().

In a list of length n, there are n+1 valid index values, from 0 to n, inclusive.

Note that the remove() and set(Object) methods are not defined in terms of the cursor position; they are defined to operate on the last element returned by a call to next() or previous().

http://72.5.124.55/j2se/1.4.2/docs/api/java/util/ListIterator.html

Page 50: COSC2767: Object-Oriented Programming

50

Vector Like ArrayList, class Vector provides the capabilities of array-like data

structures that can resize themselves dynamically. Recall that class ArrayList’s behavior and capabilities are similar to

those of class Vector, except that ArrayLists do not provide synchronization by default. We cover class Vector here primarily because it is the superclass of class Stack.

At any time, a Vector contains a number of elements that is less than or equal to its capacity. The capacity is the space that has been reserved for the Vector’s elements. If a Vector requires additional capacity, it grows by a capacity increment that you specify or by a default capacity increment. If you do not specify a capacity increment or specify one that is less than or equal to zero, the system will double the size of a Vector each time additional capacity is needed.

//VectorTest.java

http://java.sun.com/j2se/1.4.2/docs/api/java/util/Vector.html

Page 51: COSC2767: Object-Oriented Programming

51

Summary Polymorphic variable

Self, super, this, base Generics

Parameterized classes or functions Template in C++

Function template Class template

Java Generics List ArrayList LinkedList Vector

Page 52: COSC2767: Object-Oriented Programming

52

Can Even Be Used with User Defined Types

class Fraction { public: Fraction (int top, int bottom) { t = top; b = bottom; } int numerator() { return t; } int denominator() { return b; } bool operator < (Fraction & right) { return t * right.b < right.t * b; } private: int t, b; }; Fraction x(3, 4); Fraction y(7, 8); Fraction z = max(x, y); //fraction.cpp