Genericity
Motivation
Genericity
Kinds of Genericity
Generic Classes
Genericity in Java
Summary
Motivation
Important qualities of software systems
Reusability
The ability of software elements to serve for the construction of
many different applications.
Extendibility
The ease of adapting software products to changes of
specification.
To yield a higher degree of extendibility and reusability the class
construct must be more flexible!!
Two directions
Abstraction and specialization
realized by means of inheritance
Type parameterization
known as genericity
© Horst Lichter, RWTH Aachen 2
Extension Alternatives
Inheritance Abstraction
Set
OfCars
Type parameterization Genericity
List List List
OfCities OfCars OfPersons
LinkedList
OfCars
Specialization
© Horst Lichter, RWTH Aachen 3
© Horst Lichter, RWTH Aachen 4
Type-safe Calls
How can we define consistent container classes?
e.g. list of geometric objects
without genericity
What
happens if
Point p = new Point();
we are
Rectangle r = new Rectangle();
wrong?
List geoObjects = new ArrayList();
geoObjects.add(p);
geoObjects.add(r);
Point p1 = (Point)geoObjects.get(0);
Rectangle r1 = (Rectangle)geoObjects.get(1);
© Horst Lichter, RWTH Aachen 5
Approaches
1. Wait until run-time
if types don’t match, trigger a run-time failure
Smalltalk
2. Convert (“cast”) all values to a universal type
such as “pointer to void” in C
3. Parameterize the class
Defining an explicit name to the type
of container elements.
Eiffel, Ada, Java ...
© Horst Lichter, RWTH Aachen 6
Static Typing
Type safe call
x.m()
the object attached to x has a method corresponding to the
signature of m
Generalizes to calls with arguments, x.m (a, b)
Statically typed language
Type checking is performed during compile-time
static type checker
Dynamically typed language
The majority of type checking is performed at run-time.
In dynamic typing, values have types but variables do not
A variable can refer to a value of any type.
Smalltalk, Ruby
© Horst Lichter, RWTH Aachen 7
Generic Class and Generic Deviation
Formal generic parameter
class ArrayList<E> {
boolean contains (E element) {…}
void add(int index, E element){…}
boolean isEmpty() {…}
…
} Actual generic parameter
ArrayList<Point> loP = new ArrayList<Point>();
ArrayList<ArrayList<Point>> lloP = new ArrayList<ArrayList<Point>>();
Generic deviation resulting a
new type !
© Horst Lichter, RWTH Aachen 8
Kinds of Genericity
Unconstrained genericity
Every type can be used as actual generic parameter in a generic
deviation
Example:
List <E>
List<Integer> List<Account>
Constrained genericity
Admissible types of generic deviations must be subtypes of the
given formal generic parameter type
Example:
public static <T extends Comparable<T>> T max(T x, T y, T z) …
max("Hello", "new", "world");
max(new Date(2354123), new Date (547676645), new Date(456213));
© Horst Lichter, RWTH Aachen 9
Example: Constrained Genericity
A vector storing elements
Vectors can be added
class VECTOR [E]
feature sum (other : VECTOR [E]): VECTOR [E]
-- Sum of current vector and other.
do
...
end
...
end
© Horst Lichter, RWTH Aachen 10
Actual Generic Parameters must be constrained
class VECTOR [E]
feature sum (other : VECTOR [E]): VECTOR [E]
create Result.make (lower, upper);
from
i := lower until i > upper
loop
a := item (i);
b := other.item (i);
c := a + b; -- requires + operation on E!
Result.put (c, i);
i := i + 1;
end
end
© Horst Lichter, RWTH Aachen 11
Possible Solution
class VECTOR [G –> NUMERIC ]
feature
...
end
Class NUMERIC provides methods "+", "-"and so on.
Generic deviations are restricted to subtypes of type NUMERIC
© Horst Lichter, RWTH Aachen 12
Polymorphic Containers
LinkedList<RectangularShape> geoObjects = new
LinkedList<RectangularShape>();
geoObjects.add (new Rectangle2D.Double());
geoObjects.add (new RoundRectangle2D.Double());
geoObjects.add (new Ellipse2D.Double());
© Horst Lichter, RWTH Aachen 13
© Horst Lichter, RWTH Aachen 14
Genericity in Java
Which entities can be generic?
Classes, Interfaces
Methods
What kinds of genericity are supported?
Unconstrained
Constrained
Remarks
Only reference types are allowed as type parameters
no primitive types like int, double etc.
Unboxing and boxing is used to convert primitive types to
corresponding reference types and vice versa
e.g. int to Integer
© Horst Lichter, RWTH Aachen 15
Generic Classes
declaration of unconstrained
formal generic type parameters
public class Tuple<T, U> {
private final T first;
private final U second;
public Tuple(T first, U second) {
this.first = first;
this.second = second;
}
public T getFirst() {return first;}
public U getSecond() {return second;}
} actual generic parameters
Tuple<String, Integer> pair = new Tuple<String, Integer>("one",1);
int i = pair.getSecond();
generic deviation
© Horst Lichter, RWTH Aachen 16
Generic Methods
A method which declares a type variable
type variable
public class ListUtils {
public static <T> List<T> toList(T[] arrayOfTelems) {
List<T> list = new ArrayList<T>();
for (T tElem : arrayOfTelems)
list.add(tElem);
return list;
}
}
boxing: int -> Integer
List<Integer> ints = ListUtils.<Integer>toList(new Integer[] { 1, 2, 3 });
List<String> words = ListUtils.<String>toList(new String[] {"hi", "world"});
explicit actual type parameter
© Horst Lichter, RWTH Aachen 17
Constrained Genericity
public class NumList1<E extends Number> { … }
public class NumList2<E extends Number & Comparable<E>> { … }
NumList1<AtomicLong> lList1 = new NumList1<AtomicLong>();
NumList2<Integer> intList = new NumList2<Integer>();
NumberList2<AtomicLong> lList2 = new NumList2<AtomicLong>();
subtype of Number and Comparable<> ??
Covariant generic deviation
Admissible actual type parameters are constrained to be
subtypes of the formal generic parameter type
© Horst Lichter, RWTH Aachen 18
Generics and Subtyping
List<String> ls = new ArrayList<String>(); // 1
List<Object> lo = ls; // 2
lo.add(new Object()); // 3
String s = ls.get(0); // 4
In general:
If B is a subtype of A, and G is some generic type declaration, it is
not the case that G<B> is a subtype of G<A>.
© Horst Lichter, RWTH Aachen 19
Flexible Generic Types - Wildcards
static void printCollection(Collection<Object> c) {
for (Object e : c) {
System.out.println(e);
}
}
We need to declare the supertype of all Collection types!
static void printCollection(Collection<?> c) {
for (Object e : c) {
System.out.println(e); Collection of
} unknown
}
Collection<?> c = new ArrayList<String>();
c.add(new Object());
© Horst Lichter, RWTH Aachen 20
Bounded Wildcards
public class Canvas {
public void drawAll(List<GeoObject> shapes) {
for (GeoObject: shapes) {
s.draw(this);
}
...
public class Canvas {
public void drawAll(List<? extends GeoObject> shapes) {
for (GeoObject: shapes) {
s.draw(this);
}
...
© Horst Lichter, RWTH Aachen 21
Summary
Genericity
is a means to enhance reusability and extendibility
is a kind of parametric polymorphism
Generic entities must be deviated to yield non-generic ones
actual generic parameters
Sometimes actual generic parameters have to be constrained
constrained genericity
Java supports genericity
classes, interfaces and methods
constrained and unconstrained genericity
© Horst Lichter, RWTH Aachen 22