Genericity Generic Class Common Generic Classes Your Generic

advertisement
Generic Class
• One that is parameterized by type
» Works when feature semantics is common to a set
of types
• On object declaration the parameter is assigned a
type
Genericity
» For example
Parameterizing by Type
catalogue : ARRAY [ PERSON ]
» We want an array of references to persons
» All the array operations for catalogue are
customized to use persons
1
Common Generic Classes
2
Your Generic Classes
• Collection classes – classes that are collections of
objects
• You can write generic classes
• Why is this useful?
» Strong typing requires specifying a type
» But feature semantics is independent of type
» reuse
» reliability
• Examples
» Sets, Stacks, Arrays, Queues, Sequences
a : ARRAY [ MATRIX_ELEMENT ]
a : ARRAY [ INTEGER ]
a : ARRAY [ STACK [ ELEPHANTS ] ]
3
4
Understanding Genericity
Generic Stack
• We need
»
class STACK [ G ] feature
count : INTEGER -- number of elements
lists of INTEGER, lists of BOOK, lists of STRING etc.
• Without genericity we have
»
empty : BOOLEAN is do ... end
INTEGER_LIST, BOOK_LIST, STRING_LIST
full : BOOLEAN is do ... end
• Problem — Reusability.
»
The basic operations (e.g. add, remove) are essentially
the same.
»
Have to re-write essentially the same code over and
over again.
»
Violation of the Single Choice Principle — changing
LIST requires multiple changes, instead of a change at
a single point.
item : G is do ... end
put ( x : G ) is do ... end
remove is do ... end
end -- STACK
• Can use parameter G wherever a type is expected
5
Generic Array
6
Using the Generic Array
circus : ARRAY [ STACK [ ELEPHANTS ] ]
create circus.make ( 1 , 200 )
class ARRAY [ P ] creation make
feature
make ( minIndex , maxIndex : INTEGER ) is do ... end
lower, upper, count : INTEGER
st_el : STACK [ ELEPHANTS ] -- element to put in the array
create st_el
put ( value : P ; index : INTEGER ) is do ... end
circus.put ( st_el , 30 ) -- put an element into the array
item alias “[]”, infix “@” (i:INTEGER): P is do ... end
st_el2 : STACK [ ELEPHANTS ]
end -- ARRAY
st_el2 := circus @ 101
st_el2 := circus[101]
7
-- get an element from the array
-- alternative notation
8
Types of Genericity
Constrained Genericity
• Types
• Used when the generic type parameters must satisfy
some conditions
» Unconstrained
» Constrained
• The following makes sense only if P has the
feature ≥
• The previous examples showed unconstrained
genericity
class VECTOR [ P ] feature
...
minimum ( x , y : P ) : P is do
if x ≥ y then
Result := y
How we enforce
else
constraints is
Result := x
discussed in
end
Inheritance Techniques
...
end
» Any type could be passed as a parameter
9
Discussion on Genericity
10
Non-generic Java Stack
public class Stack {
private int count;
private int capacity;
private int capacityIncrement;
private Object[] itemArray; // instead of ARRAY[G]
• What programming languages offer genericity that
you know of? Java? C++? Other?
• C++ has the template: Set < int > s ;
• Java 5 has added genericity
Stack() {
//constructor limited to class name
count= 0;
capacity= 10;
capacityIncrement= 5;
itemArray= new Object[capacity];
}
• What is the effect of genericity on
» compile time
» size of the generated code
» execution time
» execution space
public boolean empty() {
return (count == 0);
}
• Warning: generics cheap in Eiffel – expensive in C++
11
12
Java Stack (cont.)
Java Stack (cont.)
public void push(Object x) {
if(count == capacity) {
capacity += capacityIncrement;
public Object peek() {
if(count == 0)
Object[] tempArray= new Object[capacity];
for(int i=0; i < count; i++)
tempArray[i]= itemArray[i];
return null;
else return itemArray[count-1];
}
itemArray= tempArray;
}
itemArray[count++]= x;
}
}
public Object pop() {
public class Point {
if(count == 0)
return null;
else return itemArray[--count];
public int x;
public int y;
}
}
13
Java Stack runtime error
14
Does run-time vs. compile time matter?
class testStack {
• Principle: When flying a plane, run-time is too late to
find out that you don’t have landing gear!
public static void main(String[] args) {
Stack s = new Stack();
Point up p erRight = new Point();
up p erRight.x= 1280;
// b reaks information hiding
up p erRight.y= 1024;
// cannot guarantee any contract
• Always better to catch errors at compile time!
• This is the main purpose of Strong Typing [OOSC2,
Chapter 17].
s.p ush("red");
s.p ush("green");
// p ush some String
s.p ush("b lue");
// ob jects on the stack
s.p ush(up p erRight);
// p ush a POINT ob ject on the stack
while(!s.emp ty()) {
• Genericity helps to enforce Strong Typing, i.e. no runtime typing errors
» LIST[INTEGER]
» LIST[BOOK]
» LIST[STRING]
// cast all items from OBJEC T
String color = (String) s.p op ();
// to STRING in order to p rint
System.out.p rintln(color);
}}}
// causes a run-time error
// C lassC astExcep tion: Point at testStack.main(testStack.java:18)
// W ith genericity, it is a compile time error
15
16